*** empty log message ***
[deliverable/binutils-gdb.git] / gdb / tracepoint.c
CommitLineData
c906108c 1/* Tracing functionality for remote targets in custom GDB protocol
9f60d481 2
8acc9f48 3 Copyright (C) 1997-2013 Free Software Foundation, Inc.
c906108c 4
c5aa993b 5 This file is part of GDB.
c906108c 6
c5aa993b
JM
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
a9762ec7 9 the Free Software Foundation; either version 3 of the License, or
c5aa993b 10 (at your option) any later version.
c906108c 11
c5aa993b
JM
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
c906108c 16
c5aa993b 17 You should have received a copy of the GNU General Public License
a9762ec7 18 along with this program. If not, see <http://www.gnu.org/licenses/>. */
c906108c
SS
19
20#include "defs.h"
5af949e3 21#include "arch-utils.h"
c906108c
SS
22#include "symtab.h"
23#include "frame.h"
c906108c
SS
24#include "gdbtypes.h"
25#include "expression.h"
26#include "gdbcmd.h"
27#include "value.h"
28#include "target.h"
29#include "language.h"
30#include "gdb_string.h"
104c1213 31#include "inferior.h"
1042e4c0 32#include "breakpoint.h"
104c1213 33#include "tracepoint.h"
c5f0f3d0 34#include "linespec.h"
4e052eda 35#include "regcache.h"
c94fdfd0 36#include "completer.h"
fe898f56 37#include "block.h"
de4f826b 38#include "dictionary.h"
383f836e 39#include "observer.h"
029a67e4 40#include "user-regs.h"
79a45b7d 41#include "valprint.h"
41575630 42#include "gdbcore.h"
768a979c 43#include "objfiles.h"
35b1e5cc 44#include "filenames.h"
00bf0b85 45#include "gdbthread.h"
2c58c0a9 46#include "stack.h"
fce3c1f0 47#include "gdbcore.h"
176a6961 48#include "remote.h"
0fb4aa4b 49#include "source.h"
c906108c
SS
50#include "ax.h"
51#include "ax-gdb.h"
2a7498d8 52#include "memrange.h"
e93a69ed 53#include "exceptions.h"
3065dfb6 54#include "cli/cli-utils.h"
55aa24fb 55#include "probe.h"
d0353e76 56#include "ctf.h"
9852c492 57#include "completer.h"
614c279d 58#include "filestuff.h"
c906108c
SS
59
60/* readline include files */
dbda9972
AC
61#include "readline/readline.h"
62#include "readline/history.h"
c906108c
SS
63
64/* readline defines this. */
65#undef savestring
66
67#ifdef HAVE_UNISTD_H
68#include <unistd.h>
69#endif
70
00bf0b85
SS
71#ifndef O_LARGEFILE
72#define O_LARGEFILE 0
73#endif
74
d183932d
MS
75/* Maximum length of an agent aexpression.
76 This accounts for the fact that packets are limited to 400 bytes
c906108c
SS
77 (which includes everything -- including the checksum), and assumes
78 the worst case of maximum length for each of the pieces of a
79 continuation packet.
c5aa993b 80
c906108c
SS
81 NOTE: expressions get mem2hex'ed otherwise this would be twice as
82 large. (400 - 31)/2 == 184 */
83#define MAX_AGENT_EXPR_LEN 184
84
98c5b216
TT
85/* A hook used to notify the UI of tracepoint operations. */
86
87void (*deprecated_trace_find_hook) (char *arg, int from_tty);
88void (*deprecated_trace_start_stop_hook) (int start, int from_tty);
c906108c 89
9a4105ab
AC
90extern void (*deprecated_readline_begin_hook) (char *, ...);
91extern char *(*deprecated_readline_hook) (char *);
92extern void (*deprecated_readline_end_hook) (void);
c906108c 93
c906108c
SS
94/*
95 Tracepoint.c:
96
97 This module defines the following debugger commands:
98 trace : set a tracepoint on a function, line, or address.
99 info trace : list all debugger-defined tracepoints.
100 delete trace : delete one or more tracepoints.
101 enable trace : enable one or more tracepoints.
102 disable trace : disable one or more tracepoints.
103 actions : specify actions to be taken at a tracepoint.
104 passcount : specify a pass count for a tracepoint.
105 tstart : start a trace experiment.
106 tstop : stop a trace experiment.
107 tstatus : query the status of a trace experiment.
108 tfind : find a trace frame in the trace buffer.
109 tdump : print everything collected at the current tracepoint.
110 save-tracepoints : write tracepoint setup into a file.
111
112 This module defines the following user-visible debugger variables:
113 $trace_frame : sequence number of trace frame currently being debugged.
114 $trace_line : source line of trace frame currently being debugged.
115 $trace_file : source file of trace frame currently being debugged.
116 $tracepoint : tracepoint number of trace frame currently being debugged.
c5aa993b 117 */
c906108c
SS
118
119
120/* ======= Important global variables: ======= */
121
f61e138d
SS
122/* The list of all trace state variables. We don't retain pointers to
123 any of these for any reason - API is by name or number only - so it
124 works to have a vector of objects. */
125
126typedef struct trace_state_variable tsv_s;
127DEF_VEC_O(tsv_s);
128
129static VEC(tsv_s) *tvariables;
130
131/* The next integer to assign to a variable. */
132
133static int next_tsv_number = 1;
134
c906108c
SS
135/* Number of last traceframe collected. */
136static int traceframe_number;
137
138/* Tracepoint for last traceframe collected. */
139static int tracepoint_number;
140
c378eb4e 141/* Symbol for function for last traceframe collected. */
c906108c
SS
142static struct symbol *traceframe_fun;
143
c378eb4e 144/* Symtab and line for last traceframe collected. */
c906108c
SS
145static struct symtab_and_line traceframe_sal;
146
b3b9301e
PA
147/* The traceframe info of the current traceframe. NULL if we haven't
148 yet attempted to fetch it, or if the target does not support
149 fetching this object, or if we're not inspecting a traceframe
150 presently. */
151static struct traceframe_info *traceframe_info;
152
c378eb4e 153/* Tracing command lists. */
c906108c
SS
154static struct cmd_list_element *tfindlist;
155
236f1d4d 156/* List of expressions to collect by default at each tracepoint hit. */
35b1e5cc 157char *default_collect = "";
236f1d4d 158
d5551862
SS
159static int disconnected_tracing;
160
4daf5ac0
SS
161/* This variable controls whether we ask the target for a linear or
162 circular trace buffer. */
163
164static int circular_trace_buffer;
165
f6f899bf
HAQ
166/* This variable is the requested trace buffer size, or -1 to indicate
167 that we don't care and leave it up to the target to set a size. */
168
169static int trace_buffer_size = -1;
170
f196051f
SS
171/* Textual notes applying to the current and/or future trace runs. */
172
173char *trace_user = NULL;
174
175/* Textual notes applying to the current and/or future trace runs. */
176
177char *trace_notes = NULL;
178
179/* Textual notes applying to the stopping of a trace. */
180
181char *trace_stop_notes = NULL;
182
c906108c 183/* ======= Important command functions: ======= */
a14ed312
KB
184static void trace_actions_command (char *, int);
185static void trace_start_command (char *, int);
186static void trace_stop_command (char *, int);
187static void trace_status_command (char *, int);
188static void trace_find_command (char *, int);
189static void trace_find_pc_command (char *, int);
190static void trace_find_tracepoint_command (char *, int);
191static void trace_find_line_command (char *, int);
192static void trace_find_range_command (char *, int);
193static void trace_find_outside_command (char *, int);
a14ed312 194static void trace_dump_command (char *, int);
c906108c
SS
195
196/* support routines */
c906108c
SS
197
198struct collection_list;
a14ed312 199static void add_aexpr (struct collection_list *, struct agent_expr *);
47b667de 200static char *mem2hex (gdb_byte *, char *, int);
a14ed312
KB
201static void add_register (struct collection_list *collection,
202 unsigned int regno);
392a587b 203
00bf0b85
SS
204static void free_uploaded_tps (struct uploaded_tp **utpp);
205static void free_uploaded_tsvs (struct uploaded_tsv **utsvp);
206
207
a14ed312 208extern void _initialize_tracepoint (void);
c906108c 209
00bf0b85
SS
210static struct trace_status trace_status;
211
212char *stop_reason_names[] = {
213 "tunknown",
214 "tnotrun",
215 "tstop",
216 "tfull",
217 "tdisconnected",
6c28cbf2
SS
218 "tpasscount",
219 "terror"
00bf0b85
SS
220};
221
222struct trace_status *
eeae04df 223current_trace_status (void)
00bf0b85
SS
224{
225 return &trace_status;
226}
227
b3b9301e
PA
228/* Destroy INFO. */
229
230static void
231free_traceframe_info (struct traceframe_info *info)
232{
233 if (info != NULL)
234 {
235 VEC_free (mem_range_s, info->memory);
236
237 xfree (info);
238 }
239}
240
7a9dd1b2 241/* Free and clear the traceframe info cache of the current
b3b9301e
PA
242 traceframe. */
243
244static void
245clear_traceframe_info (void)
246{
247 free_traceframe_info (traceframe_info);
248 traceframe_info = NULL;
249}
250
c906108c
SS
251/* Set traceframe number to NUM. */
252static void
fba45db2 253set_traceframe_num (int num)
c906108c
SS
254{
255 traceframe_number = num;
4fa62494 256 set_internalvar_integer (lookup_internalvar ("trace_frame"), num);
c906108c
SS
257}
258
259/* Set tracepoint number to NUM. */
260static void
fba45db2 261set_tracepoint_num (int num)
c906108c
SS
262{
263 tracepoint_number = num;
4fa62494 264 set_internalvar_integer (lookup_internalvar ("tracepoint"), num);
c906108c
SS
265}
266
267/* Set externally visible debug variables for querying/printing
c378eb4e 268 the traceframe context (line, function, file). */
c906108c
SS
269
270static void
fb14de7b 271set_traceframe_context (struct frame_info *trace_frame)
c906108c 272{
fb14de7b
UW
273 CORE_ADDR trace_pc;
274
dba09041
PA
275 /* Save as globals for internal use. */
276 if (trace_frame != NULL
277 && get_frame_pc_if_available (trace_frame, &trace_pc))
278 {
279 traceframe_sal = find_pc_line (trace_pc, 0);
280 traceframe_fun = find_pc_function (trace_pc);
281
282 /* Save linenumber as "$trace_line", a debugger variable visible to
283 users. */
284 set_internalvar_integer (lookup_internalvar ("trace_line"),
285 traceframe_sal.line);
286 }
287 else
c906108c 288 {
dba09041
PA
289 init_sal (&traceframe_sal);
290 traceframe_fun = NULL;
4fa62494 291 set_internalvar_integer (lookup_internalvar ("trace_line"), -1);
c906108c
SS
292 }
293
d183932d
MS
294 /* Save func name as "$trace_func", a debugger variable visible to
295 users. */
4fa62494
UW
296 if (traceframe_fun == NULL
297 || SYMBOL_LINKAGE_NAME (traceframe_fun) == NULL)
298 clear_internalvar (lookup_internalvar ("trace_func"));
c906108c 299 else
78267919
UW
300 set_internalvar_string (lookup_internalvar ("trace_func"),
301 SYMBOL_LINKAGE_NAME (traceframe_fun));
c906108c 302
d183932d
MS
303 /* Save file name as "$trace_file", a debugger variable visible to
304 users. */
4e04028d 305 if (traceframe_sal.symtab == NULL)
4fa62494 306 clear_internalvar (lookup_internalvar ("trace_file"));
c906108c 307 else
78267919 308 set_internalvar_string (lookup_internalvar ("trace_file"),
05cba821 309 symtab_to_filename_for_display (traceframe_sal.symtab));
c906108c
SS
310}
311
f61e138d
SS
312/* Create a new trace state variable with the given name. */
313
314struct trace_state_variable *
315create_trace_state_variable (const char *name)
316{
317 struct trace_state_variable tsv;
318
319 memset (&tsv, 0, sizeof (tsv));
40e1c229 320 tsv.name = xstrdup (name);
f61e138d
SS
321 tsv.number = next_tsv_number++;
322 return VEC_safe_push (tsv_s, tvariables, &tsv);
323}
324
325/* Look for a trace state variable of the given name. */
326
327struct trace_state_variable *
328find_trace_state_variable (const char *name)
329{
330 struct trace_state_variable *tsv;
331 int ix;
332
333 for (ix = 0; VEC_iterate (tsv_s, tvariables, ix, tsv); ++ix)
334 if (strcmp (name, tsv->name) == 0)
335 return tsv;
336
337 return NULL;
338}
339
70221824 340static void
f61e138d
SS
341delete_trace_state_variable (const char *name)
342{
343 struct trace_state_variable *tsv;
344 int ix;
345
346 for (ix = 0; VEC_iterate (tsv_s, tvariables, ix, tsv); ++ix)
347 if (strcmp (name, tsv->name) == 0)
348 {
134a2066
YQ
349 observer_notify_tsv_deleted (tsv);
350
40e1c229 351 xfree ((void *)tsv->name);
f61e138d 352 VEC_unordered_remove (tsv_s, tvariables, ix);
bb25a15c 353
f61e138d
SS
354 return;
355 }
356
357 warning (_("No trace variable named \"$%s\", not deleting"), name);
358}
359
1773c82c
HAQ
360/* Throws an error if NAME is not valid syntax for a trace state
361 variable's name. */
362
363void
364validate_trace_state_variable_name (const char *name)
365{
366 const char *p;
367
368 if (*name == '\0')
369 error (_("Must supply a non-empty variable name"));
370
371 /* All digits in the name is reserved for value history
372 references. */
373 for (p = name; isdigit (*p); p++)
374 ;
375 if (*p == '\0')
376 error (_("$%s is not a valid trace state variable name"), name);
377
378 for (p = name; isalnum (*p) || *p == '_'; p++)
379 ;
380 if (*p != '\0')
381 error (_("$%s is not a valid trace state variable name"), name);
382}
383
f61e138d
SS
384/* The 'tvariable' command collects a name and optional expression to
385 evaluate into an initial value. */
386
70221824 387static void
f61e138d
SS
388trace_variable_command (char *args, int from_tty)
389{
f61e138d 390 struct cleanup *old_chain;
f61e138d
SS
391 LONGEST initval = 0;
392 struct trace_state_variable *tsv;
1773c82c 393 char *name, *p;
f61e138d
SS
394
395 if (!args || !*args)
1773c82c
HAQ
396 error_no_arg (_("Syntax is $NAME [ = EXPR ]"));
397
398 /* Only allow two syntaxes; "$name" and "$name=value". */
399 p = skip_spaces (args);
f61e138d 400
1773c82c
HAQ
401 if (*p++ != '$')
402 error (_("Name of trace variable should start with '$'"));
f61e138d 403
1773c82c
HAQ
404 name = p;
405 while (isalnum (*p) || *p == '_')
406 p++;
407 name = savestring (name, p - name);
408 old_chain = make_cleanup (xfree, name);
f61e138d 409
1773c82c
HAQ
410 p = skip_spaces (p);
411 if (*p != '=' && *p != '\0')
f61e138d
SS
412 error (_("Syntax must be $NAME [ = EXPR ]"));
413
1773c82c 414 validate_trace_state_variable_name (name);
f61e138d 415
1773c82c
HAQ
416 if (*p == '=')
417 initval = value_as_long (parse_and_eval (++p));
f61e138d
SS
418
419 /* If the variable already exists, just change its initial value. */
1773c82c 420 tsv = find_trace_state_variable (name);
f61e138d
SS
421 if (tsv)
422 {
134a2066
YQ
423 if (tsv->initial_value != initval)
424 {
425 tsv->initial_value = initval;
426 observer_notify_tsv_modified (tsv);
427 }
3e43a32a
MS
428 printf_filtered (_("Trace state variable $%s "
429 "now has initial value %s.\n"),
f61e138d 430 tsv->name, plongest (tsv->initial_value));
f90824dc 431 do_cleanups (old_chain);
f61e138d
SS
432 return;
433 }
434
435 /* Create a new variable. */
1773c82c 436 tsv = create_trace_state_variable (name);
f61e138d
SS
437 tsv->initial_value = initval;
438
134a2066 439 observer_notify_tsv_created (tsv);
bb25a15c 440
3e43a32a
MS
441 printf_filtered (_("Trace state variable $%s "
442 "created, with initial value %s.\n"),
f61e138d
SS
443 tsv->name, plongest (tsv->initial_value));
444
445 do_cleanups (old_chain);
446}
447
70221824 448static void
f61e138d
SS
449delete_trace_variable_command (char *args, int from_tty)
450{
2a2287c7 451 int ix;
f61e138d
SS
452 char **argv;
453 struct cleanup *back_to;
f61e138d
SS
454
455 if (args == NULL)
456 {
457 if (query (_("Delete all trace state variables? ")))
458 VEC_free (tsv_s, tvariables);
459 dont_repeat ();
bb25a15c 460 observer_notify_tsv_deleted (NULL);
f61e138d
SS
461 return;
462 }
463
464 argv = gdb_buildargv (args);
465 back_to = make_cleanup_freeargv (argv);
466
2a2287c7 467 for (ix = 0; argv[ix] != NULL; ix++)
f61e138d 468 {
2a2287c7
MS
469 if (*argv[ix] == '$')
470 delete_trace_state_variable (argv[ix] + 1);
f61e138d 471 else
2a2287c7 472 warning (_("Name \"%s\" not prefixed with '$', ignoring"), argv[ix]);
f61e138d
SS
473 }
474
475 do_cleanups (back_to);
476
477 dont_repeat ();
478}
479
40e1c229
VP
480void
481tvariables_info_1 (void)
f61e138d
SS
482{
483 struct trace_state_variable *tsv;
484 int ix;
40e1c229
VP
485 int count = 0;
486 struct cleanup *back_to;
79a45e25 487 struct ui_out *uiout = current_uiout;
f61e138d 488
40e1c229 489 if (VEC_length (tsv_s, tvariables) == 0 && !ui_out_is_mi_like_p (uiout))
f61e138d
SS
490 {
491 printf_filtered (_("No trace state variables.\n"));
492 return;
493 }
494
35b1e5cc 495 /* Try to acquire values from the target. */
4baf5cf4 496 for (ix = 0; VEC_iterate (tsv_s, tvariables, ix, tsv); ++ix, ++count)
35b1e5cc
SS
497 tsv->value_known = target_get_trace_state_variable_value (tsv->number,
498 &(tsv->value));
499
40e1c229
VP
500 back_to = make_cleanup_ui_out_table_begin_end (uiout, 3,
501 count, "trace-variables");
502 ui_out_table_header (uiout, 15, ui_left, "name", "Name");
503 ui_out_table_header (uiout, 11, ui_left, "initial", "Initial");
504 ui_out_table_header (uiout, 11, ui_left, "current", "Current");
505
506 ui_out_table_body (uiout);
f61e138d
SS
507
508 for (ix = 0; VEC_iterate (tsv_s, tvariables, ix, tsv); ++ix)
509 {
40e1c229
VP
510 struct cleanup *back_to2;
511 char *c;
512 char *name;
513
514 back_to2 = make_cleanup_ui_out_tuple_begin_end (uiout, "variable");
515
c4f7c687 516 name = concat ("$", tsv->name, (char *) NULL);
40e1c229
VP
517 make_cleanup (xfree, name);
518 ui_out_field_string (uiout, "name", name);
519 ui_out_field_string (uiout, "initial", plongest (tsv->initial_value));
520
f61e138d 521 if (tsv->value_known)
40e1c229
VP
522 c = plongest (tsv->value);
523 else if (ui_out_is_mi_like_p (uiout))
524 /* For MI, we prefer not to use magic string constants, but rather
525 omit the field completely. The difference between unknown and
526 undefined does not seem important enough to represent. */
527 c = NULL;
00bf0b85 528 else if (current_trace_status ()->running || traceframe_number >= 0)
f61e138d 529 /* The value is/was defined, but we don't have it. */
40e1c229 530 c = "<unknown>";
f61e138d
SS
531 else
532 /* It is not meaningful to ask about the value. */
40e1c229
VP
533 c = "<undefined>";
534 if (c)
535 ui_out_field_string (uiout, "current", c);
536 ui_out_text (uiout, "\n");
537
538 do_cleanups (back_to2);
f61e138d 539 }
40e1c229
VP
540
541 do_cleanups (back_to);
542}
543
544/* List all the trace state variables. */
545
546static void
547tvariables_info (char *args, int from_tty)
548{
549 tvariables_info_1 ();
f61e138d
SS
550}
551
8bf6485c
SS
552/* Stash definitions of tsvs into the given file. */
553
554void
555save_trace_state_variables (struct ui_file *fp)
556{
557 struct trace_state_variable *tsv;
558 int ix;
559
560 for (ix = 0; VEC_iterate (tsv_s, tvariables, ix, tsv); ++ix)
561 {
562 fprintf_unfiltered (fp, "tvariable $%s", tsv->name);
563 if (tsv->initial_value)
564 fprintf_unfiltered (fp, " = %s", plongest (tsv->initial_value));
565 fprintf_unfiltered (fp, "\n");
566 }
567}
568
c906108c
SS
569/* ACTIONS functions: */
570
c906108c 571/* The three functions:
c5aa993b
JM
572 collect_pseudocommand,
573 while_stepping_pseudocommand, and
574 end_actions_pseudocommand
c906108c
SS
575 are placeholders for "commands" that are actually ONLY to be used
576 within a tracepoint action list. If the actual function is ever called,
577 it means that somebody issued the "command" at the top level,
578 which is always an error. */
579
7b3ae3a6 580static void
fba45db2 581end_actions_pseudocommand (char *args, int from_tty)
c906108c 582{
8a3fe4f8 583 error (_("This command cannot be used at the top level."));
c906108c
SS
584}
585
7b3ae3a6 586static void
fba45db2 587while_stepping_pseudocommand (char *args, int from_tty)
c906108c 588{
8a3fe4f8 589 error (_("This command can only be used in a tracepoint actions list."));
c906108c
SS
590}
591
592static void
fba45db2 593collect_pseudocommand (char *args, int from_tty)
c906108c 594{
8a3fe4f8 595 error (_("This command can only be used in a tracepoint actions list."));
c906108c
SS
596}
597
6da95a67
SS
598static void
599teval_pseudocommand (char *args, int from_tty)
600{
601 error (_("This command can only be used in a tracepoint actions list."));
602}
603
3065dfb6
SS
604/* Parse any collection options, such as /s for strings. */
605
6f937416 606const char *
92bc6a20 607decode_agent_options (const char *exp, int *trace_string)
3065dfb6
SS
608{
609 struct value_print_options opts;
610
92bc6a20
TT
611 *trace_string = 0;
612
3065dfb6
SS
613 if (*exp != '/')
614 return exp;
615
616 /* Call this to borrow the print elements default for collection
617 size. */
618 get_user_print_options (&opts);
619
620 exp++;
621 if (*exp == 's')
622 {
623 if (target_supports_string_tracing ())
624 {
625 /* Allow an optional decimal number giving an explicit maximum
626 string length, defaulting it to the "print elements" value;
627 so "collect/s80 mystr" gets at most 80 bytes of string. */
92bc6a20 628 *trace_string = opts.print_max;
3065dfb6
SS
629 exp++;
630 if (*exp >= '0' && *exp <= '9')
92bc6a20 631 *trace_string = atoi (exp);
3065dfb6
SS
632 while (*exp >= '0' && *exp <= '9')
633 exp++;
634 }
635 else
636 error (_("Target does not support \"/s\" option for string tracing."));
637 }
638 else
639 error (_("Undefined collection format \"%c\"."), *exp);
640
6f937416 641 exp = skip_spaces_const (exp);
3065dfb6
SS
642
643 return exp;
644}
645
c906108c
SS
646/* Enter a list of actions for a tracepoint. */
647static void
fba45db2 648trace_actions_command (char *args, int from_tty)
c906108c 649{
d9b3f62e 650 struct tracepoint *t;
a7bdde9e 651 struct command_line *l;
c906108c 652
197f0a60 653 t = get_tracepoint_by_number (&args, NULL, 1);
7a292a7a 654 if (t)
c906108c 655 {
a7bdde9e
VP
656 char *tmpbuf =
657 xstrprintf ("Enter actions for tracepoint %d, one per line.",
d9b3f62e 658 t->base.number);
a7bdde9e
VP
659 struct cleanup *cleanups = make_cleanup (xfree, tmpbuf);
660
3e43a32a
MS
661 l = read_command_lines (tmpbuf, from_tty, 1,
662 check_tracepoint_command, t);
a7bdde9e 663 do_cleanups (cleanups);
d9b3f62e 664 breakpoint_set_commands (&t->base, l);
c906108c 665 }
5c44784c 666 /* else just return */
c906108c
SS
667}
668
fff87407
SS
669/* Report the results of checking the agent expression, as errors or
670 internal errors. */
671
672static void
35c9c7ba 673report_agent_reqs_errors (struct agent_expr *aexpr)
fff87407
SS
674{
675 /* All of the "flaws" are serious bytecode generation issues that
676 should never occur. */
35c9c7ba 677 if (aexpr->flaw != agent_flaw_none)
fff87407
SS
678 internal_error (__FILE__, __LINE__, _("expression is malformed"));
679
680 /* If analysis shows a stack underflow, GDB must have done something
681 badly wrong in its bytecode generation. */
35c9c7ba 682 if (aexpr->min_height < 0)
fff87407
SS
683 internal_error (__FILE__, __LINE__,
684 _("expression has min height < 0"));
685
686 /* Issue this error if the stack is predicted to get too deep. The
687 limit is rather arbitrary; a better scheme might be for the
688 target to report how much stack it will have available. The
689 depth roughly corresponds to parenthesization, so a limit of 20
690 amounts to 20 levels of expression nesting, which is actually
691 a pretty big hairy expression. */
35c9c7ba 692 if (aexpr->max_height > 20)
fff87407
SS
693 error (_("Expression is too complicated."));
694}
695
c906108c 696/* worker function */
fff87407 697void
6f937416 698validate_actionline (const char *line, struct breakpoint *b)
c906108c
SS
699{
700 struct cmd_list_element *c;
701 struct expression *exp = NULL;
c906108c 702 struct cleanup *old_chain = NULL;
6f937416
PA
703 const char *tmp_p;
704 const char *p;
9355b391 705 struct bp_location *loc;
fff87407 706 struct agent_expr *aexpr;
d9b3f62e 707 struct tracepoint *t = (struct tracepoint *) b;
c906108c 708
c378eb4e 709 /* If EOF is typed, *line is NULL. */
6f937416 710 if (line == NULL)
fff87407 711 return;
15255275 712
6f937416 713 p = skip_spaces_const (line);
c906108c 714
d183932d
MS
715 /* Symbol lookup etc. */
716 if (*p == '\0') /* empty line: just prompt for another line. */
fff87407 717 return;
c906108c 718
c5aa993b 719 if (*p == '#') /* comment line */
fff87407 720 return;
c906108c
SS
721
722 c = lookup_cmd (&p, cmdlist, "", -1, 1);
723 if (c == 0)
fff87407 724 error (_("`%s' is not a tracepoint action, or is ambiguous."), p);
c5aa993b 725
bbaca940 726 if (cmd_cfunc_eq (c, collect_pseudocommand))
c906108c 727 {
92bc6a20
TT
728 int trace_string = 0;
729
3065dfb6 730 if (*p == '/')
92bc6a20 731 p = decode_agent_options (p, &trace_string);
3065dfb6 732
c5aa993b 733 do
c378eb4e
MS
734 { /* Repeat over a comma-separated list. */
735 QUIT; /* Allow user to bail out with ^C. */
6f937416 736 p = skip_spaces_const (p);
c906108c 737
c378eb4e 738 if (*p == '$') /* Look for special pseudo-symbols. */
c5aa993b 739 {
0fb4aa4b
PA
740 if (0 == strncasecmp ("reg", p + 1, 3)
741 || 0 == strncasecmp ("arg", p + 1, 3)
742 || 0 == strncasecmp ("loc", p + 1, 3)
6710bf39 743 || 0 == strncasecmp ("_ret", p + 1, 4)
0fb4aa4b 744 || 0 == strncasecmp ("_sdata", p + 1, 6))
c5aa993b
JM
745 {
746 p = strchr (p, ',');
747 continue;
748 }
d183932d 749 /* else fall thru, treat p as an expression and parse it! */
c5aa993b 750 }
9355b391 751 tmp_p = p;
d9b3f62e 752 for (loc = t->base.loc; loc; loc = loc->next)
c5aa993b 753 {
6f937416
PA
754 p = tmp_p;
755 exp = parse_exp_1 (&p, loc->address,
1bb9788d 756 block_for_pc (loc->address), 1);
9355b391
SS
757 old_chain = make_cleanup (free_current_contents, &exp);
758
759 if (exp->elts[0].opcode == OP_VAR_VALUE)
c5aa993b 760 {
9355b391
SS
761 if (SYMBOL_CLASS (exp->elts[2].symbol) == LOC_CONST)
762 {
12df843f 763 error (_("constant `%s' (value %s) "
3e43a32a 764 "will not be collected."),
fff87407 765 SYMBOL_PRINT_NAME (exp->elts[2].symbol),
12df843f 766 plongest (SYMBOL_VALUE (exp->elts[2].symbol)));
9355b391 767 }
3e43a32a
MS
768 else if (SYMBOL_CLASS (exp->elts[2].symbol)
769 == LOC_OPTIMIZED_OUT)
9355b391 770 {
3e43a32a
MS
771 error (_("`%s' is optimized away "
772 "and cannot be collected."),
fff87407 773 SYMBOL_PRINT_NAME (exp->elts[2].symbol));
9355b391 774 }
c5aa993b 775 }
c906108c 776
9355b391
SS
777 /* We have something to collect, make sure that the expr to
778 bytecode translator can handle it and that it's not too
779 long. */
92bc6a20 780 aexpr = gen_trace_for_expr (loc->address, exp, trace_string);
9355b391 781 make_cleanup_free_agent_expr (aexpr);
c906108c 782
9355b391 783 if (aexpr->len > MAX_AGENT_EXPR_LEN)
fff87407 784 error (_("Expression is too complicated."));
c906108c 785
35c9c7ba 786 ax_reqs (aexpr);
c906108c 787
35c9c7ba 788 report_agent_reqs_errors (aexpr);
c906108c 789
9355b391
SS
790 do_cleanups (old_chain);
791 }
c5aa993b
JM
792 }
793 while (p && *p++ == ',');
c906108c 794 }
fff87407 795
6da95a67
SS
796 else if (cmd_cfunc_eq (c, teval_pseudocommand))
797 {
6da95a67 798 do
c378eb4e
MS
799 { /* Repeat over a comma-separated list. */
800 QUIT; /* Allow user to bail out with ^C. */
6f937416 801 p = skip_spaces_const (p);
6da95a67 802
9355b391 803 tmp_p = p;
d9b3f62e 804 for (loc = t->base.loc; loc; loc = loc->next)
9355b391 805 {
6f937416 806 p = tmp_p;
bbc13ae3 807
9355b391 808 /* Only expressions are allowed for this action. */
6f937416 809 exp = parse_exp_1 (&p, loc->address,
1bb9788d 810 block_for_pc (loc->address), 1);
9355b391 811 old_chain = make_cleanup (free_current_contents, &exp);
6da95a67 812
9355b391
SS
813 /* We have something to evaluate, make sure that the expr to
814 bytecode translator can handle it and that it's not too
815 long. */
816 aexpr = gen_eval_for_expr (loc->address, exp);
817 make_cleanup_free_agent_expr (aexpr);
6da95a67 818
9355b391 819 if (aexpr->len > MAX_AGENT_EXPR_LEN)
fff87407
SS
820 error (_("Expression is too complicated."));
821
35c9c7ba
SS
822 ax_reqs (aexpr);
823 report_agent_reqs_errors (aexpr);
6da95a67 824
9355b391
SS
825 do_cleanups (old_chain);
826 }
6da95a67
SS
827 }
828 while (p && *p++ == ',');
6da95a67 829 }
fff87407 830
bbaca940 831 else if (cmd_cfunc_eq (c, while_stepping_pseudocommand))
c906108c 832 {
6f937416 833 char *endp;
c906108c 834
6f937416
PA
835 p = skip_spaces_const (p);
836 t->step_count = strtol (p, &endp, 0);
837 if (endp == p || t->step_count == 0)
838 error (_("while-stepping step count `%s' is malformed."), line);
839 p = endp;
c906108c 840 }
fff87407 841
bbaca940 842 else if (cmd_cfunc_eq (c, end_actions_pseudocommand))
fff87407
SS
843 ;
844
c906108c 845 else
6f937416 846 error (_("`%s' is not a supported tracepoint action."), line);
74b7792f
AC
847}
848
f50e79a4
JB
849enum {
850 memrange_absolute = -1
851};
852
c5aa993b
JM
853struct memrange
854{
f50e79a4 855 int type; /* memrange_absolute for absolute memory range,
c378eb4e 856 else basereg number. */
c906108c
SS
857 bfd_signed_vma start;
858 bfd_signed_vma end;
859};
860
c5aa993b
JM
861struct collection_list
862 {
549678da 863 unsigned char regs_mask[32]; /* room for up to 256 regs */
c5aa993b
JM
864 long listsize;
865 long next_memrange;
866 struct memrange *list;
867 long aexpr_listsize; /* size of array pointed to by expr_list elt */
868 long next_aexpr_elt;
869 struct agent_expr **aexpr_list;
870
0fb4aa4b
PA
871 /* True is the user requested a collection of "$_sdata", "static
872 tracepoint data". */
873 int strace_data;
c5aa993b
JM
874 }
875tracepoint_list, stepping_list;
c906108c
SS
876
877/* MEMRANGE functions: */
878
a14ed312 879static int memrange_cmp (const void *, const void *);
c906108c 880
c378eb4e 881/* Compare memranges for qsort. */
c906108c 882static int
fba45db2 883memrange_cmp (const void *va, const void *vb)
c906108c
SS
884{
885 const struct memrange *a = va, *b = vb;
886
887 if (a->type < b->type)
888 return -1;
889 if (a->type > b->type)
c5aa993b 890 return 1;
f50e79a4 891 if (a->type == memrange_absolute)
c906108c 892 {
c5aa993b
JM
893 if ((bfd_vma) a->start < (bfd_vma) b->start)
894 return -1;
895 if ((bfd_vma) a->start > (bfd_vma) b->start)
896 return 1;
c906108c
SS
897 }
898 else
899 {
c5aa993b 900 if (a->start < b->start)
c906108c 901 return -1;
c5aa993b
JM
902 if (a->start > b->start)
903 return 1;
c906108c
SS
904 }
905 return 0;
906}
907
d183932d 908/* Sort the memrange list using qsort, and merge adjacent memranges. */
c906108c 909static void
fba45db2 910memrange_sortmerge (struct collection_list *memranges)
c906108c
SS
911{
912 int a, b;
913
c5aa993b 914 qsort (memranges->list, memranges->next_memrange,
c906108c
SS
915 sizeof (struct memrange), memrange_cmp);
916 if (memranges->next_memrange > 0)
917 {
918 for (a = 0, b = 1; b < memranges->next_memrange; b++)
919 {
1b28d0b3
PA
920 /* If memrange b overlaps or is adjacent to memrange a,
921 merge them. */
922 if (memranges->list[a].type == memranges->list[b].type
923 && memranges->list[b].start <= memranges->list[a].end)
c906108c 924 {
08807d5a
PA
925 if (memranges->list[b].end > memranges->list[a].end)
926 memranges->list[a].end = memranges->list[b].end;
c906108c
SS
927 continue; /* next b, same a */
928 }
929 a++; /* next a */
930 if (a != b)
c5aa993b 931 memcpy (&memranges->list[a], &memranges->list[b],
c906108c
SS
932 sizeof (struct memrange));
933 }
934 memranges->next_memrange = a + 1;
935 }
936}
937
d183932d 938/* Add a register to a collection list. */
392a587b 939static void
fba45db2 940add_register (struct collection_list *collection, unsigned int regno)
c906108c
SS
941{
942 if (info_verbose)
943 printf_filtered ("collect register %d\n", regno);
27e06d3e 944 if (regno >= (8 * sizeof (collection->regs_mask)))
8a3fe4f8 945 error (_("Internal: register number %d too large for tracepoint"),
c906108c 946 regno);
c5aa993b 947 collection->regs_mask[regno / 8] |= 1 << (regno % 8);
c906108c
SS
948}
949
c378eb4e 950/* Add a memrange to a collection list. */
c906108c 951static void
d183932d
MS
952add_memrange (struct collection_list *memranges,
953 int type, bfd_signed_vma base,
fba45db2 954 unsigned long len)
c906108c
SS
955{
956 if (info_verbose)
104c1213
JM
957 {
958 printf_filtered ("(%d,", type);
959 printf_vma (base);
960 printf_filtered (",%ld)\n", len);
961 }
962
f50e79a4 963 /* type: memrange_absolute == memory, other n == basereg */
c5aa993b 964 memranges->list[memranges->next_memrange].type = type;
d183932d 965 /* base: addr if memory, offset if reg relative. */
c906108c
SS
966 memranges->list[memranges->next_memrange].start = base;
967 /* len: we actually save end (base + len) for convenience */
c5aa993b 968 memranges->list[memranges->next_memrange].end = base + len;
c906108c
SS
969 memranges->next_memrange++;
970 if (memranges->next_memrange >= memranges->listsize)
971 {
972 memranges->listsize *= 2;
c5aa993b 973 memranges->list = xrealloc (memranges->list,
c906108c
SS
974 memranges->listsize);
975 }
976
3e43a32a 977 if (type != memrange_absolute) /* Better collect the base register! */
c906108c
SS
978 add_register (memranges, type);
979}
980
d183932d 981/* Add a symbol to a collection list. */
c906108c 982static void
d183932d
MS
983collect_symbol (struct collection_list *collect,
984 struct symbol *sym,
a6d9a66e 985 struct gdbarch *gdbarch,
0936ad1d 986 long frame_regno, long frame_offset,
92bc6a20
TT
987 CORE_ADDR scope,
988 int trace_string)
c906108c 989{
c5aa993b 990 unsigned long len;
104c1213 991 unsigned int reg;
c906108c 992 bfd_signed_vma offset;
400c6af0 993 int treat_as_expr = 0;
c906108c 994
c5aa993b
JM
995 len = TYPE_LENGTH (check_typedef (SYMBOL_TYPE (sym)));
996 switch (SYMBOL_CLASS (sym))
997 {
998 default:
999 printf_filtered ("%s: don't know symbol class %d\n",
3567439c 1000 SYMBOL_PRINT_NAME (sym),
d183932d 1001 SYMBOL_CLASS (sym));
c5aa993b
JM
1002 break;
1003 case LOC_CONST:
12df843f
JK
1004 printf_filtered ("constant %s (value %s) will not be collected.\n",
1005 SYMBOL_PRINT_NAME (sym), plongest (SYMBOL_VALUE (sym)));
c5aa993b
JM
1006 break;
1007 case LOC_STATIC:
1008 offset = SYMBOL_VALUE_ADDRESS (sym);
1009 if (info_verbose)
104c1213
JM
1010 {
1011 char tmp[40];
1012
1013 sprintf_vma (tmp, offset);
1014 printf_filtered ("LOC_STATIC %s: collect %ld bytes at %s.\n",
3567439c 1015 SYMBOL_PRINT_NAME (sym), len,
d183932d 1016 tmp /* address */);
104c1213 1017 }
400c6af0
SS
1018 /* A struct may be a C++ class with static fields, go to general
1019 expression handling. */
1020 if (TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_STRUCT)
1021 treat_as_expr = 1;
1022 else
1023 add_memrange (collect, memrange_absolute, offset, len);
c5aa993b
JM
1024 break;
1025 case LOC_REGISTER:
a6d9a66e 1026 reg = SYMBOL_REGISTER_OPS (sym)->register_number (sym, gdbarch);
c5aa993b 1027 if (info_verbose)
d183932d 1028 printf_filtered ("LOC_REG[parm] %s: ",
3567439c 1029 SYMBOL_PRINT_NAME (sym));
c5aa993b 1030 add_register (collect, reg);
d183932d
MS
1031 /* Check for doubles stored in two registers. */
1032 /* FIXME: how about larger types stored in 3 or more regs? */
c5aa993b 1033 if (TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_FLT &&
a6d9a66e 1034 len > register_size (gdbarch, reg))
c5aa993b
JM
1035 add_register (collect, reg + 1);
1036 break;
1037 case LOC_REF_ARG:
1038 printf_filtered ("Sorry, don't know how to do LOC_REF_ARG yet.\n");
1039 printf_filtered (" (will not collect %s)\n",
3567439c 1040 SYMBOL_PRINT_NAME (sym));
c5aa993b
JM
1041 break;
1042 case LOC_ARG:
1043 reg = frame_regno;
1044 offset = frame_offset + SYMBOL_VALUE (sym);
1045 if (info_verbose)
1046 {
104c1213 1047 printf_filtered ("LOC_LOCAL %s: Collect %ld bytes at offset ",
3567439c 1048 SYMBOL_PRINT_NAME (sym), len);
104c1213
JM
1049 printf_vma (offset);
1050 printf_filtered (" from frame ptr reg %d\n", reg);
c5aa993b
JM
1051 }
1052 add_memrange (collect, reg, offset, len);
1053 break;
1054 case LOC_REGPARM_ADDR:
1055 reg = SYMBOL_VALUE (sym);
1056 offset = 0;
1057 if (info_verbose)
1058 {
104c1213 1059 printf_filtered ("LOC_REGPARM_ADDR %s: Collect %ld bytes at offset ",
3567439c 1060 SYMBOL_PRINT_NAME (sym), len);
104c1213
JM
1061 printf_vma (offset);
1062 printf_filtered (" from reg %d\n", reg);
c5aa993b
JM
1063 }
1064 add_memrange (collect, reg, offset, len);
1065 break;
1066 case LOC_LOCAL:
c5aa993b
JM
1067 reg = frame_regno;
1068 offset = frame_offset + SYMBOL_VALUE (sym);
1069 if (info_verbose)
1070 {
104c1213 1071 printf_filtered ("LOC_LOCAL %s: Collect %ld bytes at offset ",
3567439c 1072 SYMBOL_PRINT_NAME (sym), len);
104c1213
JM
1073 printf_vma (offset);
1074 printf_filtered (" from frame ptr reg %d\n", reg);
c5aa993b
JM
1075 }
1076 add_memrange (collect, reg, offset, len);
1077 break;
a0405854 1078
c5aa993b 1079 case LOC_UNRESOLVED:
a0405854 1080 treat_as_expr = 1;
c5aa993b 1081 break;
a0405854 1082
c5aa993b 1083 case LOC_OPTIMIZED_OUT:
8e1a459b 1084 printf_filtered ("%s has been optimized out of existence.\n",
3567439c 1085 SYMBOL_PRINT_NAME (sym));
c5aa993b 1086 break;
0936ad1d
SS
1087
1088 case LOC_COMPUTED:
400c6af0 1089 treat_as_expr = 1;
0936ad1d 1090 break;
c5aa993b 1091 }
400c6af0
SS
1092
1093 /* Expressions are the most general case. */
1094 if (treat_as_expr)
1095 {
1096 struct agent_expr *aexpr;
1097 struct cleanup *old_chain1 = NULL;
400c6af0 1098
92bc6a20 1099 aexpr = gen_trace_for_var (scope, gdbarch, sym, trace_string);
400c6af0
SS
1100
1101 /* It can happen that the symbol is recorded as a computed
1102 location, but it's been optimized away and doesn't actually
1103 have a location expression. */
1104 if (!aexpr)
1105 {
1106 printf_filtered ("%s has been optimized out of existence.\n",
1107 SYMBOL_PRINT_NAME (sym));
1108 return;
1109 }
1110
1111 old_chain1 = make_cleanup_free_agent_expr (aexpr);
1112
35c9c7ba 1113 ax_reqs (aexpr);
fff87407 1114
35c9c7ba 1115 report_agent_reqs_errors (aexpr);
400c6af0
SS
1116
1117 discard_cleanups (old_chain1);
1118 add_aexpr (collect, aexpr);
1119
c378eb4e 1120 /* Take care of the registers. */
35c9c7ba 1121 if (aexpr->reg_mask_len > 0)
400c6af0
SS
1122 {
1123 int ndx1, ndx2;
1124
35c9c7ba 1125 for (ndx1 = 0; ndx1 < aexpr->reg_mask_len; ndx1++)
400c6af0 1126 {
c378eb4e 1127 QUIT; /* Allow user to bail out with ^C. */
35c9c7ba 1128 if (aexpr->reg_mask[ndx1] != 0)
400c6af0 1129 {
c378eb4e 1130 /* Assume chars have 8 bits. */
400c6af0 1131 for (ndx2 = 0; ndx2 < 8; ndx2++)
35c9c7ba 1132 if (aexpr->reg_mask[ndx1] & (1 << ndx2))
c378eb4e 1133 /* It's used -- record it. */
400c6af0
SS
1134 add_register (collect, ndx1 * 8 + ndx2);
1135 }
1136 }
1137 }
1138 }
c906108c
SS
1139}
1140
2c58c0a9
PA
1141/* Data to be passed around in the calls to the locals and args
1142 iterators. */
1143
1144struct add_local_symbols_data
1145{
1146 struct collection_list *collect;
1147 struct gdbarch *gdbarch;
1148 CORE_ADDR pc;
1149 long frame_regno;
1150 long frame_offset;
1151 int count;
92bc6a20 1152 int trace_string;
2c58c0a9
PA
1153};
1154
c378eb4e 1155/* The callback for the locals and args iterators. */
2c58c0a9
PA
1156
1157static void
1158do_collect_symbol (const char *print_name,
1159 struct symbol *sym,
1160 void *cb_data)
1161{
1162 struct add_local_symbols_data *p = cb_data;
1163
1164 collect_symbol (p->collect, sym, p->gdbarch, p->frame_regno,
92bc6a20 1165 p->frame_offset, p->pc, p->trace_string);
2c58c0a9
PA
1166 p->count++;
1167}
1168
c378eb4e 1169/* Add all locals (or args) symbols to collection list. */
c906108c 1170static void
a6d9a66e
UW
1171add_local_symbols (struct collection_list *collect,
1172 struct gdbarch *gdbarch, CORE_ADDR pc,
92bc6a20
TT
1173 long frame_regno, long frame_offset, int type,
1174 int trace_string)
c906108c 1175{
c5aa993b 1176 struct block *block;
2c58c0a9
PA
1177 struct add_local_symbols_data cb_data;
1178
1179 cb_data.collect = collect;
1180 cb_data.gdbarch = gdbarch;
1181 cb_data.pc = pc;
1182 cb_data.frame_regno = frame_regno;
1183 cb_data.frame_offset = frame_offset;
1184 cb_data.count = 0;
92bc6a20 1185 cb_data.trace_string = trace_string;
c906108c 1186
2c58c0a9 1187 if (type == 'L')
c906108c 1188 {
2c58c0a9
PA
1189 block = block_for_pc (pc);
1190 if (block == NULL)
c906108c 1191 {
2c58c0a9
PA
1192 warning (_("Can't collect locals; "
1193 "no symbol table info available.\n"));
1194 return;
c906108c 1195 }
2c58c0a9
PA
1196
1197 iterate_over_block_local_vars (block, do_collect_symbol, &cb_data);
1198 if (cb_data.count == 0)
1199 warning (_("No locals found in scope."));
1200 }
1201 else
1202 {
1203 pc = get_pc_function_start (pc);
1204 block = block_for_pc (pc);
1205 if (block == NULL)
1206 {
b37520b6 1207 warning (_("Can't collect args; no symbol table info available."));
2c58c0a9
PA
1208 return;
1209 }
1210
1211 iterate_over_block_arg_vars (block, do_collect_symbol, &cb_data);
1212 if (cb_data.count == 0)
1213 warning (_("No args found in scope."));
c906108c 1214 }
c906108c
SS
1215}
1216
0fb4aa4b
PA
1217static void
1218add_static_trace_data (struct collection_list *collection)
1219{
1220 if (info_verbose)
1221 printf_filtered ("collect static trace data\n");
1222 collection->strace_data = 1;
1223}
1224
c906108c
SS
1225/* worker function */
1226static void
fba45db2 1227clear_collection_list (struct collection_list *list)
c906108c
SS
1228{
1229 int ndx;
1230
1231 list->next_memrange = 0;
1232 for (ndx = 0; ndx < list->next_aexpr_elt; ndx++)
1233 {
c5aa993b 1234 free_agent_expr (list->aexpr_list[ndx]);
c906108c
SS
1235 list->aexpr_list[ndx] = NULL;
1236 }
1237 list->next_aexpr_elt = 0;
1238 memset (list->regs_mask, 0, sizeof (list->regs_mask));
0fb4aa4b 1239 list->strace_data = 0;
c906108c
SS
1240}
1241
c378eb4e 1242/* Reduce a collection list to string form (for gdb protocol). */
c906108c 1243static char **
a73e3634 1244stringify_collection_list (struct collection_list *list)
c906108c
SS
1245{
1246 char temp_buf[2048];
104c1213 1247 char tmp2[40];
c906108c
SS
1248 int count;
1249 int ndx = 0;
1250 char *(*str_list)[];
1251 char *end;
c5aa993b 1252 long i;
c906108c 1253
0fb4aa4b 1254 count = 1 + 1 + list->next_memrange + list->next_aexpr_elt + 1;
c5aa993b 1255 str_list = (char *(*)[]) xmalloc (count * sizeof (char *));
c906108c 1256
0fb4aa4b
PA
1257 if (list->strace_data)
1258 {
1259 if (info_verbose)
1260 printf_filtered ("\nCollecting static trace data\n");
1261 end = temp_buf;
1262 *end++ = 'L';
1263 (*str_list)[ndx] = savestring (temp_buf, end - temp_buf);
1264 ndx++;
1265 }
1266
c906108c 1267 for (i = sizeof (list->regs_mask) - 1; i > 0; i--)
c378eb4e 1268 if (list->regs_mask[i] != 0) /* Skip leading zeroes in regs_mask. */
c906108c 1269 break;
c378eb4e 1270 if (list->regs_mask[i] != 0) /* Prepare to send regs_mask to the stub. */
c906108c
SS
1271 {
1272 if (info_verbose)
1273 printf_filtered ("\nCollecting registers (mask): 0x");
1274 end = temp_buf;
c5aa993b 1275 *end++ = 'R';
c906108c
SS
1276 for (; i >= 0; i--)
1277 {
c378eb4e 1278 QUIT; /* Allow user to bail out with ^C. */
c906108c
SS
1279 if (info_verbose)
1280 printf_filtered ("%02X", list->regs_mask[i]);
c5aa993b 1281 sprintf (end, "%02X", list->regs_mask[i]);
c906108c
SS
1282 end += 2;
1283 }
1b36a34b 1284 (*str_list)[ndx] = xstrdup (temp_buf);
c906108c
SS
1285 ndx++;
1286 }
1287 if (info_verbose)
1288 printf_filtered ("\n");
1289 if (list->next_memrange > 0 && info_verbose)
1290 printf_filtered ("Collecting memranges: \n");
1291 for (i = 0, count = 0, end = temp_buf; i < list->next_memrange; i++)
1292 {
c378eb4e 1293 QUIT; /* Allow user to bail out with ^C. */
104c1213 1294 sprintf_vma (tmp2, list->list[i].start);
c906108c 1295 if (info_verbose)
104c1213
JM
1296 {
1297 printf_filtered ("(%d, %s, %ld)\n",
1298 list->list[i].type,
1299 tmp2,
1300 (long) (list->list[i].end - list->list[i].start));
1301 }
c906108c
SS
1302 if (count + 27 > MAX_AGENT_EXPR_LEN)
1303 {
c5aa993b 1304 (*str_list)[ndx] = savestring (temp_buf, count);
c906108c
SS
1305 ndx++;
1306 count = 0;
1307 end = temp_buf;
1308 }
104c1213 1309
d1948716
JB
1310 {
1311 bfd_signed_vma length = list->list[i].end - list->list[i].start;
1312
1313 /* The "%X" conversion specifier expects an unsigned argument,
f50e79a4
JB
1314 so passing -1 (memrange_absolute) to it directly gives you
1315 "FFFFFFFF" (or more, depending on sizeof (unsigned)).
1316 Special-case it. */
1317 if (list->list[i].type == memrange_absolute)
d1948716
JB
1318 sprintf (end, "M-1,%s,%lX", tmp2, (long) length);
1319 else
1320 sprintf (end, "M%X,%s,%lX", list->list[i].type, tmp2, (long) length);
1321 }
104c1213 1322
c906108c 1323 count += strlen (end);
3ffbc0a5 1324 end = temp_buf + count;
c906108c
SS
1325 }
1326
1327 for (i = 0; i < list->next_aexpr_elt; i++)
1328 {
c378eb4e 1329 QUIT; /* Allow user to bail out with ^C. */
c906108c
SS
1330 if ((count + 10 + 2 * list->aexpr_list[i]->len) > MAX_AGENT_EXPR_LEN)
1331 {
c5aa993b 1332 (*str_list)[ndx] = savestring (temp_buf, count);
c906108c
SS
1333 ndx++;
1334 count = 0;
1335 end = temp_buf;
1336 }
1337 sprintf (end, "X%08X,", list->aexpr_list[i]->len);
1338 end += 10; /* 'X' + 8 hex digits + ',' */
1339 count += 10;
1340
d183932d
MS
1341 end = mem2hex (list->aexpr_list[i]->buf,
1342 end, list->aexpr_list[i]->len);
c906108c
SS
1343 count += 2 * list->aexpr_list[i]->len;
1344 }
1345
1346 if (count != 0)
1347 {
c5aa993b 1348 (*str_list)[ndx] = savestring (temp_buf, count);
c906108c
SS
1349 ndx++;
1350 count = 0;
1351 end = temp_buf;
1352 }
1353 (*str_list)[ndx] = NULL;
1354
1355 if (ndx == 0)
27e06d3e 1356 {
6c761d9c 1357 xfree (str_list);
27e06d3e
MS
1358 return NULL;
1359 }
c906108c
SS
1360 else
1361 return *str_list;
1362}
1363
a7bdde9e
VP
1364
1365static void
1366encode_actions_1 (struct command_line *action,
a7bdde9e
VP
1367 struct bp_location *tloc,
1368 int frame_reg,
1369 LONGEST frame_offset,
1370 struct collection_list *collect,
1371 struct collection_list *stepping_list)
c906108c 1372{
6f937416 1373 const char *action_exp;
c5aa993b 1374 struct expression *exp = NULL;
104c1213 1375 int i;
f976f6d4 1376 struct value *tempval;
c906108c
SS
1377 struct cmd_list_element *cmd;
1378 struct agent_expr *aexpr;
236f1d4d
SS
1379
1380 for (; action; action = action->next)
c906108c 1381 {
c378eb4e 1382 QUIT; /* Allow user to bail out with ^C. */
a7bdde9e 1383 action_exp = action->line;
6f937416 1384 action_exp = skip_spaces_const (action_exp);
c906108c 1385
c906108c
SS
1386 cmd = lookup_cmd (&action_exp, cmdlist, "", -1, 1);
1387 if (cmd == 0)
8a3fe4f8 1388 error (_("Bad action list item: %s"), action_exp);
c906108c 1389
bbaca940 1390 if (cmd_cfunc_eq (cmd, collect_pseudocommand))
c906108c 1391 {
92bc6a20
TT
1392 int trace_string = 0;
1393
3065dfb6 1394 if (*action_exp == '/')
92bc6a20 1395 action_exp = decode_agent_options (action_exp, &trace_string);
3065dfb6 1396
c5aa993b 1397 do
c378eb4e
MS
1398 { /* Repeat over a comma-separated list. */
1399 QUIT; /* Allow user to bail out with ^C. */
6f937416 1400 action_exp = skip_spaces_const (action_exp);
c906108c 1401
c5aa993b
JM
1402 if (0 == strncasecmp ("$reg", action_exp, 4))
1403 {
3e05895e 1404 for (i = 0; i < gdbarch_num_regs (tloc->gdbarch); i++)
c5aa993b
JM
1405 add_register (collect, i);
1406 action_exp = strchr (action_exp, ','); /* more? */
1407 }
1408 else if (0 == strncasecmp ("$arg", action_exp, 4))
1409 {
1410 add_local_symbols (collect,
3e05895e 1411 tloc->gdbarch,
9355b391 1412 tloc->address,
c5aa993b
JM
1413 frame_reg,
1414 frame_offset,
92bc6a20
TT
1415 'A',
1416 trace_string);
c5aa993b
JM
1417 action_exp = strchr (action_exp, ','); /* more? */
1418 }
1419 else if (0 == strncasecmp ("$loc", action_exp, 4))
1420 {
1421 add_local_symbols (collect,
3e05895e 1422 tloc->gdbarch,
9355b391 1423 tloc->address,
c5aa993b
JM
1424 frame_reg,
1425 frame_offset,
92bc6a20
TT
1426 'L',
1427 trace_string);
c5aa993b
JM
1428 action_exp = strchr (action_exp, ','); /* more? */
1429 }
6710bf39
SS
1430 else if (0 == strncasecmp ("$_ret", action_exp, 5))
1431 {
1432 struct cleanup *old_chain1 = NULL;
1433
1434 aexpr = gen_trace_for_return_address (tloc->address,
92bc6a20
TT
1435 tloc->gdbarch,
1436 trace_string);
6710bf39
SS
1437
1438 old_chain1 = make_cleanup_free_agent_expr (aexpr);
1439
1440 ax_reqs (aexpr);
1441 report_agent_reqs_errors (aexpr);
1442
1443 discard_cleanups (old_chain1);
1444 add_aexpr (collect, aexpr);
1445
1446 /* take care of the registers */
1447 if (aexpr->reg_mask_len > 0)
1448 {
1449 int ndx1, ndx2;
1450
1451 for (ndx1 = 0; ndx1 < aexpr->reg_mask_len; ndx1++)
1452 {
1453 QUIT; /* allow user to bail out with ^C */
1454 if (aexpr->reg_mask[ndx1] != 0)
1455 {
1456 /* assume chars have 8 bits */
1457 for (ndx2 = 0; ndx2 < 8; ndx2++)
1458 if (aexpr->reg_mask[ndx1] & (1 << ndx2))
1459 /* it's used -- record it */
1460 add_register (collect,
1461 ndx1 * 8 + ndx2);
1462 }
1463 }
1464 }
1465
1466 action_exp = strchr (action_exp, ','); /* more? */
1467 }
0fb4aa4b
PA
1468 else if (0 == strncasecmp ("$_sdata", action_exp, 7))
1469 {
1470 add_static_trace_data (collect);
1471 action_exp = strchr (action_exp, ','); /* more? */
1472 }
c5aa993b
JM
1473 else
1474 {
744a8059 1475 unsigned long addr;
c5aa993b
JM
1476 struct cleanup *old_chain = NULL;
1477 struct cleanup *old_chain1 = NULL;
c5aa993b 1478
6f937416 1479 exp = parse_exp_1 (&action_exp, tloc->address,
9355b391 1480 block_for_pc (tloc->address), 1);
74b7792f 1481 old_chain = make_cleanup (free_current_contents, &exp);
c906108c 1482
c5aa993b
JM
1483 switch (exp->elts[0].opcode)
1484 {
1485 case OP_REGISTER:
67f3407f
DJ
1486 {
1487 const char *name = &exp->elts[2].string;
1488
3e05895e 1489 i = user_reg_map_name_to_regnum (tloc->gdbarch,
029a67e4 1490 name, strlen (name));
67f3407f
DJ
1491 if (i == -1)
1492 internal_error (__FILE__, __LINE__,
1493 _("Register $%s not available"),
1494 name);
1495 if (info_verbose)
1496 printf_filtered ("OP_REGISTER: ");
1497 add_register (collect, i);
1498 break;
1499 }
c5aa993b
JM
1500
1501 case UNOP_MEMVAL:
c378eb4e 1502 /* Safe because we know it's a simple expression. */
c5aa993b 1503 tempval = evaluate_expression (exp);
42ae5230 1504 addr = value_address (tempval);
744a8059
SP
1505 /* Initialize the TYPE_LENGTH if it is a typedef. */
1506 check_typedef (exp->elts[1].type);
1507 add_memrange (collect, memrange_absolute, addr,
1508 TYPE_LENGTH (exp->elts[1].type));
c5aa993b
JM
1509 break;
1510
1511 case OP_VAR_VALUE:
1512 collect_symbol (collect,
1513 exp->elts[2].symbol,
3e05895e 1514 tloc->gdbarch,
c5aa993b 1515 frame_reg,
0936ad1d 1516 frame_offset,
92bc6a20
TT
1517 tloc->address,
1518 trace_string);
c5aa993b
JM
1519 break;
1520
c378eb4e 1521 default: /* Full-fledged expression. */
92bc6a20
TT
1522 aexpr = gen_trace_for_expr (tloc->address, exp,
1523 trace_string);
c5aa993b 1524
f23d52e0 1525 old_chain1 = make_cleanup_free_agent_expr (aexpr);
c5aa993b 1526
35c9c7ba 1527 ax_reqs (aexpr);
c5aa993b 1528
35c9c7ba 1529 report_agent_reqs_errors (aexpr);
c5aa993b
JM
1530
1531 discard_cleanups (old_chain1);
1532 add_aexpr (collect, aexpr);
1533
c378eb4e 1534 /* Take care of the registers. */
35c9c7ba 1535 if (aexpr->reg_mask_len > 0)
c906108c 1536 {
c5aa993b
JM
1537 int ndx1;
1538 int ndx2;
1539
35c9c7ba 1540 for (ndx1 = 0; ndx1 < aexpr->reg_mask_len; ndx1++)
c906108c 1541 {
c378eb4e 1542 QUIT; /* Allow user to bail out with ^C. */
35c9c7ba 1543 if (aexpr->reg_mask[ndx1] != 0)
c5aa993b 1544 {
c378eb4e 1545 /* Assume chars have 8 bits. */
c5aa993b 1546 for (ndx2 = 0; ndx2 < 8; ndx2++)
35c9c7ba 1547 if (aexpr->reg_mask[ndx1] & (1 << ndx2))
c378eb4e 1548 /* It's used -- record it. */
d183932d
MS
1549 add_register (collect,
1550 ndx1 * 8 + ndx2);
c5aa993b 1551 }
c906108c
SS
1552 }
1553 }
c5aa993b
JM
1554 break;
1555 } /* switch */
1556 do_cleanups (old_chain);
1557 } /* do */
1558 }
1559 while (action_exp && *action_exp++ == ',');
1560 } /* if */
6da95a67
SS
1561 else if (cmd_cfunc_eq (cmd, teval_pseudocommand))
1562 {
1563 do
c378eb4e
MS
1564 { /* Repeat over a comma-separated list. */
1565 QUIT; /* Allow user to bail out with ^C. */
6f937416 1566 action_exp = skip_spaces_const (action_exp);
6da95a67
SS
1567
1568 {
6da95a67
SS
1569 struct cleanup *old_chain = NULL;
1570 struct cleanup *old_chain1 = NULL;
6da95a67 1571
6f937416 1572 exp = parse_exp_1 (&action_exp, tloc->address,
9355b391 1573 block_for_pc (tloc->address), 1);
6da95a67
SS
1574 old_chain = make_cleanup (free_current_contents, &exp);
1575
9355b391 1576 aexpr = gen_eval_for_expr (tloc->address, exp);
6da95a67
SS
1577 old_chain1 = make_cleanup_free_agent_expr (aexpr);
1578
35c9c7ba
SS
1579 ax_reqs (aexpr);
1580 report_agent_reqs_errors (aexpr);
6da95a67
SS
1581
1582 discard_cleanups (old_chain1);
1583 /* Even though we're not officially collecting, add
1584 to the collect list anyway. */
1585 add_aexpr (collect, aexpr);
1586
1587 do_cleanups (old_chain);
1588 } /* do */
1589 }
1590 while (action_exp && *action_exp++ == ',');
1591 } /* if */
bbaca940 1592 else if (cmd_cfunc_eq (cmd, while_stepping_pseudocommand))
c906108c 1593 {
a7bdde9e
VP
1594 /* We check against nested while-stepping when setting
1595 breakpoint action, so no way to run into nested
1596 here. */
1597 gdb_assert (stepping_list);
1598
23da373a 1599 encode_actions_1 (action->body_list[0], tloc, frame_reg,
2a2287c7 1600 frame_offset, stepping_list, NULL);
c906108c 1601 }
a7bdde9e
VP
1602 else
1603 error (_("Invalid tracepoint command '%s'"), action->line);
1604 } /* for */
1605}
1606
1607/* Render all actions into gdb protocol. */
5fbce5df
PA
1608
1609void
23da373a
YQ
1610encode_actions (struct bp_location *tloc, char ***tdp_actions,
1611 char ***stepping_actions)
a7bdde9e 1612{
a7bdde9e
VP
1613 char *default_collect_line = NULL;
1614 struct command_line *actions;
1615 struct command_line *default_collect_action = NULL;
1616 int frame_reg;
1617 LONGEST frame_offset;
1618 struct cleanup *back_to;
1619
1620 back_to = make_cleanup (null_cleanup, NULL);
1621
1622 clear_collection_list (&tracepoint_list);
1623 clear_collection_list (&stepping_list);
1624
1625 *tdp_actions = NULL;
1626 *stepping_actions = NULL;
1627
3e05895e
TT
1628 gdbarch_virtual_frame_pointer (tloc->gdbarch,
1629 tloc->address, &frame_reg, &frame_offset);
a7bdde9e 1630
23da373a 1631 actions = breakpoint_commands (tloc->owner);
a7bdde9e
VP
1632
1633 /* If there are default expressions to collect, make up a collect
1634 action and prepend to the action list to encode. Note that since
1635 validation is per-tracepoint (local var "xyz" might be valid for
1636 one tracepoint and not another, etc), we make up the action on
1637 the fly, and don't cache it. */
1638 if (*default_collect)
1639 {
a7bdde9e
VP
1640 default_collect_line = xstrprintf ("collect %s", default_collect);
1641 make_cleanup (xfree, default_collect_line);
1642
23da373a 1643 validate_actionline (default_collect_line, tloc->owner);
fff87407
SS
1644
1645 default_collect_action = xmalloc (sizeof (struct command_line));
1646 make_cleanup (xfree, default_collect_action);
5cea2a26 1647 default_collect_action->next = actions;
6f937416 1648 default_collect_action->line = default_collect_line;
fff87407 1649 actions = default_collect_action;
a7bdde9e 1650 }
23da373a 1651 encode_actions_1 (actions, tloc, frame_reg, frame_offset,
a7bdde9e
VP
1652 &tracepoint_list, &stepping_list);
1653
c5aa993b
JM
1654 memrange_sortmerge (&tracepoint_list);
1655 memrange_sortmerge (&stepping_list);
c906108c 1656
a73e3634
YQ
1657 *tdp_actions = stringify_collection_list (&tracepoint_list);
1658 *stepping_actions = stringify_collection_list (&stepping_list);
236f1d4d 1659
a7bdde9e 1660 do_cleanups (back_to);
c906108c
SS
1661}
1662
1663static void
fba45db2 1664add_aexpr (struct collection_list *collect, struct agent_expr *aexpr)
c906108c
SS
1665{
1666 if (collect->next_aexpr_elt >= collect->aexpr_listsize)
1667 {
1668 collect->aexpr_list =
1669 xrealloc (collect->aexpr_list,
5d502164 1670 2 * collect->aexpr_listsize * sizeof (struct agent_expr *));
c906108c
SS
1671 collect->aexpr_listsize *= 2;
1672 }
1673 collect->aexpr_list[collect->next_aexpr_elt] = aexpr;
1674 collect->next_aexpr_elt++;
1675}
1676
bfccc43c
YQ
1677static void
1678process_tracepoint_on_disconnect (void)
1679{
1680 VEC(breakpoint_p) *tp_vec = NULL;
1681 int ix;
1682 struct breakpoint *b;
1683 int has_pending_p = 0;
1684
1685 /* Check whether we still have pending tracepoint. If we have, warn the
1686 user that pending tracepoint will no longer work. */
1687 tp_vec = all_tracepoints ();
1688 for (ix = 0; VEC_iterate (breakpoint_p, tp_vec, ix, b); ix++)
1689 {
1690 if (b->loc == NULL)
1691 {
1692 has_pending_p = 1;
1693 break;
1694 }
1695 else
1696 {
1697 struct bp_location *loc1;
1698
1699 for (loc1 = b->loc; loc1; loc1 = loc1->next)
1700 {
1701 if (loc1->shlib_disabled)
1702 {
1703 has_pending_p = 1;
1704 break;
1705 }
1706 }
1707
1708 if (has_pending_p)
1709 break;
1710 }
1711 }
1712 VEC_free (breakpoint_p, tp_vec);
1713
1714 if (has_pending_p)
1715 warning (_("Pending tracepoints will not be resolved while"
1716 " GDB is disconnected\n"));
1717}
1718
c5aa993b 1719
f224b49d 1720void
f196051f 1721start_tracing (char *notes)
d183932d 1722{
1042e4c0
SS
1723 VEC(breakpoint_p) *tp_vec = NULL;
1724 int ix;
d9b3f62e 1725 struct breakpoint *b;
f61e138d 1726 struct trace_state_variable *tsv;
d914c394 1727 int any_enabled = 0, num_to_download = 0;
f196051f
SS
1728 int ret;
1729
35b1e5cc 1730 tp_vec = all_tracepoints ();
76a2b958 1731
c378eb4e 1732 /* No point in tracing without any tracepoints... */
76a2b958
SS
1733 if (VEC_length (breakpoint_p, tp_vec) == 0)
1734 {
1735 VEC_free (breakpoint_p, tp_vec);
1736 error (_("No tracepoints defined, not starting trace"));
1737 }
1738
d9b3f62e 1739 for (ix = 0; VEC_iterate (breakpoint_p, tp_vec, ix, b); ix++)
76a2b958 1740 {
d9b3f62e 1741 struct tracepoint *t = (struct tracepoint *) b;
55aa24fb 1742 struct bp_location *loc;
d9b3f62e
PA
1743
1744 if (b->enable_state == bp_enabled)
d914c394
SS
1745 any_enabled = 1;
1746
d9b3f62e 1747 if ((b->type == bp_fast_tracepoint
d914c394
SS
1748 ? may_insert_fast_tracepoints
1749 : may_insert_tracepoints))
1750 ++num_to_download;
1751 else
1752 warning (_("May not insert %stracepoints, skipping tracepoint %d"),
d9b3f62e 1753 (b->type == bp_fast_tracepoint ? "fast " : ""), b->number);
76a2b958
SS
1754 }
1755
76a2b958
SS
1756 if (!any_enabled)
1757 {
d248b706
KY
1758 if (target_supports_enable_disable_tracepoint ())
1759 warning (_("No tracepoints enabled"));
1760 else
1761 {
1762 /* No point in tracing with only disabled tracepoints that
1763 cannot be re-enabled. */
1764 VEC_free (breakpoint_p, tp_vec);
1765 error (_("No tracepoints enabled, not starting trace"));
1766 }
76a2b958
SS
1767 }
1768
d914c394
SS
1769 if (num_to_download <= 0)
1770 {
1771 VEC_free (breakpoint_p, tp_vec);
1772 error (_("No tracepoints that may be downloaded, not starting trace"));
1773 }
1774
76a2b958
SS
1775 target_trace_init ();
1776
d9b3f62e 1777 for (ix = 0; VEC_iterate (breakpoint_p, tp_vec, ix, b); ix++)
7a697b8d 1778 {
d9b3f62e 1779 struct tracepoint *t = (struct tracepoint *) b;
e8ba3115 1780 struct bp_location *loc;
f2a8bc8a 1781 int bp_location_downloaded = 0;
d9b3f62e 1782
4511b1ba
YQ
1783 /* Clear `inserted' flag. */
1784 for (loc = b->loc; loc; loc = loc->next)
1785 loc->inserted = 0;
1786
d9b3f62e 1787 if ((b->type == bp_fast_tracepoint
d914c394
SS
1788 ? !may_insert_fast_tracepoints
1789 : !may_insert_tracepoints))
1790 continue;
1791
35b1e5cc 1792 t->number_on_target = 0;
e8ba3115
YQ
1793
1794 for (loc = b->loc; loc; loc = loc->next)
1e4d1764
YQ
1795 {
1796 /* Since tracepoint locations are never duplicated, `inserted'
1797 flag should be zero. */
1798 gdb_assert (!loc->inserted);
1799
1800 target_download_tracepoint (loc);
1801
1802 loc->inserted = 1;
f2a8bc8a 1803 bp_location_downloaded = 1;
1e4d1764 1804 }
e8ba3115 1805
d9b3f62e 1806 t->number_on_target = b->number;
55aa24fb
SDJ
1807
1808 for (loc = b->loc; loc; loc = loc->next)
311fe7e1
SDJ
1809 if (loc->probe != NULL)
1810 loc->probe->pops->set_semaphore (loc->probe, loc->gdbarch);
f2a8bc8a
YQ
1811
1812 if (bp_location_downloaded)
1813 observer_notify_breakpoint_modified (b);
7a697b8d 1814 }
35b1e5cc 1815 VEC_free (breakpoint_p, tp_vec);
76a2b958 1816
00bf0b85 1817 /* Send down all the trace state variables too. */
35b1e5cc 1818 for (ix = 0; VEC_iterate (tsv_s, tvariables, ix, tsv); ++ix)
782b2b07 1819 {
00bf0b85 1820 target_download_trace_state_variable (tsv);
782b2b07 1821 }
35b1e5cc
SS
1822
1823 /* Tell target to treat text-like sections as transparent. */
1824 target_trace_set_readonly_regions ();
4daf5ac0
SS
1825 /* Set some mode flags. */
1826 target_set_disconnected_tracing (disconnected_tracing);
1827 target_set_circular_trace_buffer (circular_trace_buffer);
f6f899bf 1828 target_set_trace_buffer_size (trace_buffer_size);
1042e4c0 1829
f196051f
SS
1830 if (!notes)
1831 notes = trace_notes;
1832 ret = target_set_trace_notes (trace_user, notes, NULL);
1833
1834 if (!ret && (trace_user || notes))
43011e52 1835 warning (_("Target does not support trace user/notes, info ignored"));
f196051f 1836
35b1e5cc
SS
1837 /* Now insert traps and begin collecting data. */
1838 target_trace_start ();
1042e4c0 1839
35b1e5cc
SS
1840 /* Reset our local state. */
1841 set_traceframe_num (-1);
1842 set_tracepoint_num (-1);
1843 set_traceframe_context (NULL);
00bf0b85 1844 current_trace_status()->running = 1;
b3b9301e 1845 clear_traceframe_info ();
1042e4c0
SS
1846}
1847
f196051f
SS
1848/* The tstart command requests the target to start a new trace run.
1849 The command passes any arguments it has to the target verbatim, as
1850 an optional "trace note". This is useful as for instance a warning
1851 to other users if the trace runs disconnected, and you don't want
1852 anybody else messing with the target. */
f224b49d
VP
1853
1854static void
1855trace_start_command (char *args, int from_tty)
1856{
1857 dont_repeat (); /* Like "run", dangerous to repeat accidentally. */
1858
615bcdef
SS
1859 if (current_trace_status ()->running)
1860 {
1861 if (from_tty
1862 && !query (_("A trace is running already. Start a new run? ")))
1863 error (_("New trace run not started."));
1864 }
1865
f196051f 1866 start_tracing (args);
f224b49d
VP
1867}
1868
f196051f
SS
1869/* The tstop command stops the tracing run. The command passes any
1870 supplied arguments to the target verbatim as a "stop note"; if the
1871 target supports trace notes, then it will be reported back as part
1872 of the trace run's status. */
1873
c906108c 1874static void
fba45db2 1875trace_stop_command (char *args, int from_tty)
d183932d 1876{
615bcdef
SS
1877 if (!current_trace_status ()->running)
1878 error (_("Trace is not running."));
1879
f196051f 1880 stop_tracing (args);
c906108c
SS
1881}
1882
d5551862 1883void
f196051f 1884stop_tracing (char *note)
d5551862 1885{
f196051f 1886 int ret;
55aa24fb
SDJ
1887 VEC(breakpoint_p) *tp_vec = NULL;
1888 int ix;
1889 struct breakpoint *t;
f196051f 1890
35b1e5cc 1891 target_trace_stop ();
f196051f 1892
55aa24fb
SDJ
1893 tp_vec = all_tracepoints ();
1894 for (ix = 0; VEC_iterate (breakpoint_p, tp_vec, ix, t); ix++)
1895 {
1896 struct bp_location *loc;
1897
1898 if ((t->type == bp_fast_tracepoint
1899 ? !may_insert_fast_tracepoints
1900 : !may_insert_tracepoints))
1901 continue;
1902
1903 for (loc = t->loc; loc; loc = loc->next)
1904 {
1905 /* GDB can be totally absent in some disconnected trace scenarios,
1906 but we don't really care if this semaphore goes out of sync.
1907 That's why we are decrementing it here, but not taking care
1908 in other places. */
311fe7e1
SDJ
1909 if (loc->probe != NULL)
1910 loc->probe->pops->clear_semaphore (loc->probe, loc->gdbarch);
55aa24fb
SDJ
1911 }
1912 }
1913
1914 VEC_free (breakpoint_p, tp_vec);
1915
f196051f
SS
1916 if (!note)
1917 note = trace_stop_notes;
1918 ret = target_set_trace_notes (NULL, NULL, note);
1919
1920 if (!ret && note)
43011e52 1921 warning (_("Target does not support trace notes, note ignored"));
f196051f 1922
c378eb4e 1923 /* Should change in response to reply? */
00bf0b85 1924 current_trace_status ()->running = 0;
d5551862
SS
1925}
1926
c906108c
SS
1927/* tstatus command */
1928static void
fba45db2 1929trace_status_command (char *args, int from_tty)
d183932d 1930{
00bf0b85 1931 struct trace_status *ts = current_trace_status ();
f196051f
SS
1932 int status, ix;
1933 VEC(breakpoint_p) *tp_vec = NULL;
1934 struct breakpoint *t;
35b1e5cc 1935
00bf0b85
SS
1936 status = target_get_trace_status (ts);
1937
1938 if (status == -1)
1939 {
f5911ea1 1940 if (ts->filename != NULL)
00bf0b85
SS
1941 printf_filtered (_("Using a trace file.\n"));
1942 else
1943 {
1944 printf_filtered (_("Trace can not be run on this target.\n"));
1945 return;
1946 }
1947 }
1948
1949 if (!ts->running_known)
1950 {
1951 printf_filtered (_("Run/stop status is unknown.\n"));
1952 }
1953 else if (ts->running)
c906108c 1954 {
35b1e5cc 1955 printf_filtered (_("Trace is running on the target.\n"));
c906108c
SS
1956 }
1957 else
00bf0b85
SS
1958 {
1959 switch (ts->stop_reason)
1960 {
1961 case trace_never_run:
1962 printf_filtered (_("No trace has been run on the target.\n"));
1963 break;
1964 case tstop_command:
f196051f
SS
1965 if (ts->stop_desc)
1966 printf_filtered (_("Trace stopped by a tstop command (%s).\n"),
1967 ts->stop_desc);
1968 else
1969 printf_filtered (_("Trace stopped by a tstop command.\n"));
00bf0b85
SS
1970 break;
1971 case trace_buffer_full:
1972 printf_filtered (_("Trace stopped because the buffer was full.\n"));
1973 break;
1974 case trace_disconnected:
1975 printf_filtered (_("Trace stopped because of disconnection.\n"));
1976 break;
1977 case tracepoint_passcount:
00bf0b85
SS
1978 printf_filtered (_("Trace stopped by tracepoint %d.\n"),
1979 ts->stopping_tracepoint);
1980 break;
6c28cbf2
SS
1981 case tracepoint_error:
1982 if (ts->stopping_tracepoint)
3e43a32a
MS
1983 printf_filtered (_("Trace stopped by an "
1984 "error (%s, tracepoint %d).\n"),
f196051f 1985 ts->stop_desc, ts->stopping_tracepoint);
6c28cbf2
SS
1986 else
1987 printf_filtered (_("Trace stopped by an error (%s).\n"),
f196051f 1988 ts->stop_desc);
6c28cbf2 1989 break;
00bf0b85
SS
1990 case trace_stop_reason_unknown:
1991 printf_filtered (_("Trace stopped for an unknown reason.\n"));
1992 break;
1993 default:
1994 printf_filtered (_("Trace stopped for some other reason (%d).\n"),
1995 ts->stop_reason);
1996 break;
1997 }
1998 }
1999
4daf5ac0
SS
2000 if (ts->traceframes_created >= 0
2001 && ts->traceframe_count != ts->traceframes_created)
2002 {
3e43a32a
MS
2003 printf_filtered (_("Buffer contains %d trace "
2004 "frames (of %d created total).\n"),
4daf5ac0
SS
2005 ts->traceframe_count, ts->traceframes_created);
2006 }
2007 else if (ts->traceframe_count >= 0)
00bf0b85
SS
2008 {
2009 printf_filtered (_("Collected %d trace frames.\n"),
2010 ts->traceframe_count);
2011 }
2012
4daf5ac0 2013 if (ts->buffer_free >= 0)
00bf0b85 2014 {
4daf5ac0
SS
2015 if (ts->buffer_size >= 0)
2016 {
2017 printf_filtered (_("Trace buffer has %d bytes of %d bytes free"),
2018 ts->buffer_free, ts->buffer_size);
2019 if (ts->buffer_size > 0)
2020 printf_filtered (_(" (%d%% full)"),
2021 ((int) ((((long long) (ts->buffer_size
2022 - ts->buffer_free)) * 100)
2023 / ts->buffer_size)));
2024 printf_filtered (_(".\n"));
2025 }
2026 else
2027 printf_filtered (_("Trace buffer has %d bytes free.\n"),
2028 ts->buffer_free);
00bf0b85 2029 }
35b1e5cc 2030
33da3f1c
SS
2031 if (ts->disconnected_tracing)
2032 printf_filtered (_("Trace will continue if GDB disconnects.\n"));
2033 else
2034 printf_filtered (_("Trace will stop if GDB disconnects.\n"));
2035
2036 if (ts->circular_buffer)
2037 printf_filtered (_("Trace buffer is circular.\n"));
2038
f196051f
SS
2039 if (ts->user_name && strlen (ts->user_name) > 0)
2040 printf_filtered (_("Trace user is %s.\n"), ts->user_name);
2041
2042 if (ts->notes && strlen (ts->notes) > 0)
2043 printf_filtered (_("Trace notes: %s.\n"), ts->notes);
2044
00bf0b85 2045 /* Now report on what we're doing with tfind. */
35b1e5cc
SS
2046 if (traceframe_number >= 0)
2047 printf_filtered (_("Looking at trace frame %d, tracepoint %d.\n"),
2048 traceframe_number, tracepoint_number);
2049 else
2050 printf_filtered (_("Not looking at any trace frame.\n"));
f196051f
SS
2051
2052 /* Report start/stop times if supplied. */
2053 if (ts->start_time)
2054 {
2055 if (ts->stop_time)
2056 {
2057 LONGEST run_time = ts->stop_time - ts->start_time;
2058
2059 /* Reporting a run time is more readable than two long numbers. */
2060 printf_filtered (_("Trace started at %ld.%06ld secs, stopped %ld.%06ld secs later.\n"),
7f767d10
SS
2061 (long int) ts->start_time / 1000000,
2062 (long int) ts->start_time % 1000000,
2063 (long int) run_time / 1000000,
2064 (long int) run_time % 1000000);
f196051f
SS
2065 }
2066 else
2067 printf_filtered (_("Trace started at %ld.%06ld secs.\n"),
7f767d10
SS
2068 (long int) ts->start_time / 1000000,
2069 (long int) ts->start_time % 1000000);
f196051f
SS
2070 }
2071 else if (ts->stop_time)
2072 printf_filtered (_("Trace stopped at %ld.%06ld secs.\n"),
7f767d10
SS
2073 (long int) ts->stop_time / 1000000,
2074 (long int) ts->stop_time % 1000000);
f196051f
SS
2075
2076 /* Now report any per-tracepoint status available. */
2077 tp_vec = all_tracepoints ();
2078
2079 for (ix = 0; VEC_iterate (breakpoint_p, tp_vec, ix, t); ix++)
2080 target_get_tracepoint_status (t, NULL);
2081
2082 VEC_free (breakpoint_p, tp_vec);
c906108c
SS
2083}
2084
f224b49d
VP
2085/* Report the trace status to uiout, in a way suitable for MI, and not
2086 suitable for CLI. If ON_STOP is true, suppress a few fields that
2087 are not meaningful in the -trace-stop response.
2088
2089 The implementation is essentially parallel to trace_status_command, but
2090 merging them will result in unreadable code. */
2091void
2092trace_status_mi (int on_stop)
2093{
79a45e25 2094 struct ui_out *uiout = current_uiout;
f224b49d
VP
2095 struct trace_status *ts = current_trace_status ();
2096 int status;
f224b49d
VP
2097
2098 status = target_get_trace_status (ts);
2099
f5911ea1 2100 if (status == -1 && ts->filename == NULL)
f224b49d
VP
2101 {
2102 ui_out_field_string (uiout, "supported", "0");
2103 return;
2104 }
2105
f5911ea1 2106 if (ts->filename != NULL)
f224b49d
VP
2107 ui_out_field_string (uiout, "supported", "file");
2108 else if (!on_stop)
2109 ui_out_field_string (uiout, "supported", "1");
2110
f5911ea1
HAQ
2111 if (ts->filename != NULL)
2112 ui_out_field_string (uiout, "trace-file", ts->filename);
2113
f224b49d
VP
2114 gdb_assert (ts->running_known);
2115
2116 if (ts->running)
2117 {
2118 ui_out_field_string (uiout, "running", "1");
2119
2120 /* Unlike CLI, do not show the state of 'disconnected-tracing' variable.
2121 Given that the frontend gets the status either on -trace-stop, or from
2122 -trace-status after re-connection, it does not seem like this
2123 information is necessary for anything. It is not necessary for either
2124 figuring the vital state of the target nor for navigation of trace
2125 frames. If the frontend wants to show the current state is some
2126 configure dialog, it can request the value when such dialog is
2127 invoked by the user. */
2128 }
2129 else
2130 {
2131 char *stop_reason = NULL;
2132 int stopping_tracepoint = -1;
2133
2134 if (!on_stop)
2135 ui_out_field_string (uiout, "running", "0");
2136
2137 if (ts->stop_reason != trace_stop_reason_unknown)
2138 {
2139 switch (ts->stop_reason)
2140 {
2141 case tstop_command:
2142 stop_reason = "request";
2143 break;
2144 case trace_buffer_full:
2145 stop_reason = "overflow";
2146 break;
2147 case trace_disconnected:
2148 stop_reason = "disconnection";
2149 break;
2150 case tracepoint_passcount:
2151 stop_reason = "passcount";
2152 stopping_tracepoint = ts->stopping_tracepoint;
2153 break;
6c28cbf2
SS
2154 case tracepoint_error:
2155 stop_reason = "error";
2156 stopping_tracepoint = ts->stopping_tracepoint;
2157 break;
f224b49d
VP
2158 }
2159
2160 if (stop_reason)
2161 {
2162 ui_out_field_string (uiout, "stop-reason", stop_reason);
2163 if (stopping_tracepoint != -1)
2164 ui_out_field_int (uiout, "stopping-tracepoint",
2165 stopping_tracepoint);
6c28cbf2
SS
2166 if (ts->stop_reason == tracepoint_error)
2167 ui_out_field_string (uiout, "error-description",
f196051f 2168 ts->stop_desc);
f224b49d
VP
2169 }
2170 }
2171 }
2172
a97153c7 2173 if (ts->traceframe_count != -1)
f224b49d 2174 ui_out_field_int (uiout, "frames", ts->traceframe_count);
87290684
SS
2175 if (ts->traceframes_created != -1)
2176 ui_out_field_int (uiout, "frames-created", ts->traceframes_created);
a97153c7
PA
2177 if (ts->buffer_size != -1)
2178 ui_out_field_int (uiout, "buffer-size", ts->buffer_size);
2179 if (ts->buffer_free != -1)
2180 ui_out_field_int (uiout, "buffer-free", ts->buffer_free);
2181
2182 ui_out_field_int (uiout, "disconnected", ts->disconnected_tracing);
2183 ui_out_field_int (uiout, "circular", ts->circular_buffer);
f196051f
SS
2184
2185 ui_out_field_string (uiout, "user-name", ts->user_name);
2186 ui_out_field_string (uiout, "notes", ts->notes);
2187
2188 {
2189 char buf[100];
2190
2191 xsnprintf (buf, sizeof buf, "%ld.%06ld",
7f767d10
SS
2192 (long int) ts->start_time / 1000000,
2193 (long int) ts->start_time % 1000000);
f196051f
SS
2194 ui_out_field_string (uiout, "start-time", buf);
2195 xsnprintf (buf, sizeof buf, "%ld.%06ld",
7f767d10
SS
2196 (long int) ts->stop_time / 1000000,
2197 (long int) ts->stop_time % 1000000);
f196051f
SS
2198 ui_out_field_string (uiout, "stop-time", buf);
2199 }
f224b49d
VP
2200}
2201
2f9d54cf
PA
2202/* Check if a trace run is ongoing. If so, and FROM_TTY, query the
2203 user if she really wants to detach. */
2204
d5551862 2205void
2f9d54cf 2206query_if_trace_running (int from_tty)
d5551862 2207{
2f9d54cf
PA
2208 if (!from_tty)
2209 return;
2210
00bf0b85
SS
2211 /* It can happen that the target that was tracing went away on its
2212 own, and we didn't notice. Get a status update, and if the
2213 current target doesn't even do tracing, then assume it's not
2214 running anymore. */
26afc0d7 2215 if (target_get_trace_status (current_trace_status ()) < 0)
00bf0b85
SS
2216 current_trace_status ()->running = 0;
2217
33da3f1c
SS
2218 /* If running interactively, give the user the option to cancel and
2219 then decide what to do differently with the run. Scripts are
2220 just going to disconnect and let the target deal with it,
2221 according to how it's been instructed previously via
2222 disconnected-tracing. */
2f9d54cf 2223 if (current_trace_status ()->running)
d5551862 2224 {
bfccc43c
YQ
2225 process_tracepoint_on_disconnect ();
2226
33da3f1c
SS
2227 if (current_trace_status ()->disconnected_tracing)
2228 {
3e43a32a
MS
2229 if (!query (_("Trace is running and will "
2230 "continue after detach; detach anyway? ")))
33da3f1c
SS
2231 error (_("Not confirmed."));
2232 }
2233 else
2234 {
3e43a32a
MS
2235 if (!query (_("Trace is running but will "
2236 "stop on detach; detach anyway? ")))
33da3f1c
SS
2237 error (_("Not confirmed."));
2238 }
d5551862 2239 }
2f9d54cf 2240}
8b9b7ef8 2241
2f9d54cf
PA
2242/* This function handles the details of what to do about an ongoing
2243 tracing run if the user has asked to detach or otherwise disconnect
2244 from the target. */
2245
2246void
2247disconnect_tracing (void)
2248{
8b9b7ef8
SS
2249 /* Also we want to be out of tfind mode, otherwise things can get
2250 confusing upon reconnection. Just use these calls instead of
2251 full tfind_1 behavior because we're in the middle of detaching,
2252 and there's no point to updating current stack frame etc. */
e6e4e701 2253 set_current_traceframe (-1);
8d735b87 2254 set_tracepoint_num (-1);
8b9b7ef8 2255 set_traceframe_context (NULL);
d5551862
SS
2256}
2257
d183932d 2258/* Worker function for the various flavors of the tfind command. */
f197e0f1
VP
2259void
2260tfind_1 (enum trace_find_type type, int num,
cc5925ad 2261 CORE_ADDR addr1, CORE_ADDR addr2,
f197e0f1 2262 int from_tty)
c906108c
SS
2263{
2264 int target_frameno = -1, target_tracept = -1;
2ce6d6bf 2265 struct frame_id old_frame_id = null_frame_id;
d9b3f62e 2266 struct tracepoint *tp;
79a45e25 2267 struct ui_out *uiout = current_uiout;
c906108c 2268
2ce6d6bf
SS
2269 /* Only try to get the current stack frame if we have a chance of
2270 succeeding. In particular, if we're trying to get a first trace
2271 frame while all threads are running, it's not going to succeed,
2272 so leave it with a default value and let the frame comparison
2273 below (correctly) decide to print out the source location of the
2274 trace frame. */
2275 if (!(type == tfind_number && num == -1)
2276 && (has_stack_frames () || traceframe_number >= 0))
2277 old_frame_id = get_frame_id (get_current_frame ());
c906108c 2278
35b1e5cc
SS
2279 target_frameno = target_trace_find (type, num, addr1, addr2,
2280 &target_tracept);
2281
2282 if (type == tfind_number
2283 && num == -1
2284 && target_frameno == -1)
2285 {
2286 /* We told the target to get out of tfind mode, and it did. */
2287 }
2288 else if (target_frameno == -1)
2289 {
2ce6d6bf 2290 /* A request for a non-existent trace frame has failed.
35b1e5cc
SS
2291 Our response will be different, depending on FROM_TTY:
2292
2293 If FROM_TTY is true, meaning that this command was
2294 typed interactively by the user, then give an error
2295 and DO NOT change the state of traceframe_number etc.
2296
2297 However if FROM_TTY is false, meaning that we're either
2298 in a script, a loop, or a user-defined command, then
2299 DON'T give an error, but DO change the state of
2300 traceframe_number etc. to invalid.
2301
2302 The rationalle is that if you typed the command, you
2303 might just have committed a typo or something, and you'd
2304 like to NOT lose your current debugging state. However
2305 if you're in a user-defined command or especially in a
2306 loop, then you need a way to detect that the command
2307 failed WITHOUT aborting. This allows you to write
2308 scripts that search thru the trace buffer until the end,
2309 and then continue on to do something else. */
2310
2311 if (from_tty)
2312 error (_("Target failed to find requested trace frame."));
2313 else
2314 {
2315 if (info_verbose)
2316 printf_filtered ("End of trace buffer.\n");
c378eb4e 2317#if 0 /* dubious now? */
35b1e5cc
SS
2318 /* The following will not recurse, since it's
2319 special-cased. */
2320 trace_find_command ("-1", from_tty);
2321#endif
2322 }
2323 }
2324
d5551862
SS
2325 tp = get_tracepoint_by_number_on_target (target_tracept);
2326
35f196d9 2327 reinit_frame_cache ();
2f4d8875 2328 target_dcache_invalidate ();
8d735b87 2329
201b4506
YQ
2330 set_tracepoint_num (tp ? tp->base.number : target_tracept);
2331
2332 if (target_frameno != get_traceframe_number ())
2333 observer_notify_traceframe_changed (target_frameno, tracepoint_number);
2334
8d735b87
YQ
2335 set_current_traceframe (target_frameno);
2336
c906108c 2337 if (target_frameno == -1)
fb14de7b 2338 set_traceframe_context (NULL);
c906108c 2339 else
fb14de7b 2340 set_traceframe_context (get_current_frame ());
c906108c 2341
f197e0f1
VP
2342 if (traceframe_number >= 0)
2343 {
2344 /* Use different branches for MI and CLI to make CLI messages
2345 i18n-eable. */
2346 if (ui_out_is_mi_like_p (uiout))
2347 {
2348 ui_out_field_string (uiout, "found", "1");
2349 ui_out_field_int (uiout, "tracepoint", tracepoint_number);
2350 ui_out_field_int (uiout, "traceframe", traceframe_number);
2351 }
2352 else
2353 {
2354 printf_unfiltered (_("Found trace frame %d, tracepoint %d\n"),
2355 traceframe_number, tracepoint_number);
2356 }
2357 }
2358 else
2359 {
2360 if (ui_out_is_mi_like_p (uiout))
2361 ui_out_field_string (uiout, "found", "0");
4136fdd2
SS
2362 else if (type == tfind_number && num == -1)
2363 printf_unfiltered (_("No longer looking at any trace frame\n"));
c378eb4e 2364 else /* This case may never occur, check. */
4136fdd2 2365 printf_unfiltered (_("No trace frame found\n"));
f197e0f1
VP
2366 }
2367
00bf0b85
SS
2368 /* If we're in nonstop mode and getting out of looking at trace
2369 frames, there won't be any current frame to go back to and
2370 display. */
2371 if (from_tty
2372 && (has_stack_frames () || traceframe_number >= 0))
c906108c 2373 {
0faf0076 2374 enum print_what print_what;
c906108c 2375
2ce6d6bf 2376 /* NOTE: in imitation of the step command, try to determine
d183932d
MS
2377 whether we have made a transition from one function to
2378 another. If so, we'll print the "stack frame" (ie. the new
2379 function and it's arguments) -- otherwise we'll just show the
fb14de7b
UW
2380 new source line. */
2381
2382 if (frame_id_eq (old_frame_id,
2383 get_frame_id (get_current_frame ())))
0faf0076 2384 print_what = SRC_LINE;
c906108c 2385 else
0faf0076 2386 print_what = SRC_AND_LOC;
c906108c 2387
b04f3ab4 2388 print_stack_frame (get_selected_frame (NULL), 1, print_what);
c906108c
SS
2389 do_displays ();
2390 }
2391}
2392
2393/* trace_find_command takes a trace frame number n,
2394 sends "QTFrame:<n>" to the target,
2395 and accepts a reply that may contain several optional pieces
2396 of information: a frame number, a tracepoint number, and an
2397 indication of whether this is a trap frame or a stepping frame.
2398
2399 The minimal response is just "OK" (which indicates that the
2400 target does not give us a frame number or a tracepoint number).
2401 Instead of that, the target may send us a string containing
2402 any combination of:
c5aa993b
JM
2403 F<hexnum> (gives the selected frame number)
2404 T<hexnum> (gives the selected tracepoint number)
2405 */
c906108c
SS
2406
2407/* tfind command */
2408static void
fba45db2 2409trace_find_command (char *args, int from_tty)
c378eb4e 2410{ /* This should only be called with a numeric argument. */
c906108c 2411 int frameno = -1;
c906108c 2412
f5911ea1
HAQ
2413 if (current_trace_status ()->running
2414 && current_trace_status ()->filename == NULL)
a73c6dcd 2415 error (_("May not look at trace frames while trace is running."));
35b1e5cc
SS
2416
2417 if (args == 0 || *args == 0)
2418 { /* TFIND with no args means find NEXT trace frame. */
2419 if (traceframe_number == -1)
c378eb4e 2420 frameno = 0; /* "next" is first one. */
35b1e5cc
SS
2421 else
2422 frameno = traceframe_number + 1;
2423 }
2424 else if (0 == strcmp (args, "-"))
c906108c 2425 {
35b1e5cc
SS
2426 if (traceframe_number == -1)
2427 error (_("not debugging trace buffer"));
2428 else if (from_tty && traceframe_number == 0)
2429 error (_("already at start of trace buffer"));
2430
2431 frameno = traceframe_number - 1;
2432 }
2433 /* A hack to work around eval's need for fp to have been collected. */
2434 else if (0 == strcmp (args, "-1"))
2435 frameno = -1;
2436 else
2437 frameno = parse_and_eval_long (args);
c906108c 2438
35b1e5cc
SS
2439 if (frameno < -1)
2440 error (_("invalid input (%d is less than zero)"), frameno);
c906108c 2441
f197e0f1 2442 tfind_1 (tfind_number, frameno, 0, 0, from_tty);
c906108c
SS
2443}
2444
2445/* tfind end */
2446static void
fba45db2 2447trace_find_end_command (char *args, int from_tty)
c906108c
SS
2448{
2449 trace_find_command ("-1", from_tty);
2450}
2451
c906108c
SS
2452/* tfind start */
2453static void
fba45db2 2454trace_find_start_command (char *args, int from_tty)
c906108c
SS
2455{
2456 trace_find_command ("0", from_tty);
2457}
2458
2459/* tfind pc command */
2460static void
fba45db2 2461trace_find_pc_command (char *args, int from_tty)
d183932d 2462{
c906108c 2463 CORE_ADDR pc;
c906108c 2464
f5911ea1
HAQ
2465 if (current_trace_status ()->running
2466 && current_trace_status ()->filename == NULL)
a73c6dcd 2467 error (_("May not look at trace frames while trace is running."));
c906108c 2468
35b1e5cc
SS
2469 if (args == 0 || *args == 0)
2470 pc = regcache_read_pc (get_current_regcache ());
c906108c 2471 else
35b1e5cc
SS
2472 pc = parse_and_eval_address (args);
2473
f197e0f1 2474 tfind_1 (tfind_pc, 0, pc, 0, from_tty);
c906108c
SS
2475}
2476
2477/* tfind tracepoint command */
2478static void
fba45db2 2479trace_find_tracepoint_command (char *args, int from_tty)
d183932d 2480{
c906108c 2481 int tdp;
d9b3f62e 2482 struct tracepoint *tp;
c906108c 2483
f5911ea1
HAQ
2484 if (current_trace_status ()->running
2485 && current_trace_status ()->filename == NULL)
a73c6dcd 2486 error (_("May not look at trace frames while trace is running."));
383e5f85 2487
35b1e5cc
SS
2488 if (args == 0 || *args == 0)
2489 {
2490 if (tracepoint_number == -1)
2491 error (_("No current tracepoint -- please supply an argument."));
c906108c 2492 else
c378eb4e 2493 tdp = tracepoint_number; /* Default is current TDP. */
c906108c
SS
2494 }
2495 else
35b1e5cc
SS
2496 tdp = parse_and_eval_long (args);
2497
2498 /* If we have the tracepoint on hand, use the number that the
2499 target knows about (which may be different if we disconnected
2500 and reconnected). */
2501 tp = get_tracepoint (tdp);
2502 if (tp)
2503 tdp = tp->number_on_target;
2504
f197e0f1 2505 tfind_1 (tfind_tp, tdp, 0, 0, from_tty);
c906108c
SS
2506}
2507
2508/* TFIND LINE command:
c5aa993b 2509
c906108c 2510 This command will take a sourceline for argument, just like BREAK
d183932d 2511 or TRACE (ie. anything that "decode_line_1" can handle).
c5aa993b 2512
c906108c
SS
2513 With no argument, this command will find the next trace frame
2514 corresponding to a source line OTHER THAN THE CURRENT ONE. */
2515
2516static void
fba45db2 2517trace_find_line_command (char *args, int from_tty)
d183932d 2518{
c906108c
SS
2519 static CORE_ADDR start_pc, end_pc;
2520 struct symtabs_and_lines sals;
2521 struct symtab_and_line sal;
c906108c
SS
2522 struct cleanup *old_chain;
2523
f5911ea1
HAQ
2524 if (current_trace_status ()->running
2525 && current_trace_status ()->filename == NULL)
a73c6dcd 2526 error (_("May not look at trace frames while trace is running."));
5af949e3 2527
35b1e5cc
SS
2528 if (args == 0 || *args == 0)
2529 {
2530 sal = find_pc_line (get_frame_pc (get_current_frame ()), 0);
2531 sals.nelts = 1;
2532 sals.sals = (struct symtab_and_line *)
2533 xmalloc (sizeof (struct symtab_and_line));
2534 sals.sals[0] = sal;
2535 }
2536 else
42e08e69 2537 {
39cf75f7 2538 sals = decode_line_with_current_source (args, DECODE_LINE_FUNFIRSTLINE);
35b1e5cc
SS
2539 sal = sals.sals[0];
2540 }
2541
2542 old_chain = make_cleanup (xfree, sals.sals);
2543 if (sal.symtab == 0)
42e08e69
SS
2544 error (_("No line number information available."));
2545
2546 if (sal.line > 0 && find_line_pc_range (sal, &start_pc, &end_pc))
35b1e5cc
SS
2547 {
2548 if (start_pc == end_pc)
2549 {
2550 printf_filtered ("Line %d of \"%s\"",
05cba821
JK
2551 sal.line,
2552 symtab_to_filename_for_display (sal.symtab));
35b1e5cc
SS
2553 wrap_here (" ");
2554 printf_filtered (" is at address ");
2555 print_address (get_current_arch (), start_pc, gdb_stdout);
2556 wrap_here (" ");
2557 printf_filtered (" but contains no code.\n");
2558 sal = find_pc_line (start_pc, 0);
2559 if (sal.line > 0
2560 && find_line_pc_range (sal, &start_pc, &end_pc)
2561 && start_pc != end_pc)
2562 printf_filtered ("Attempting to find line %d instead.\n",
2563 sal.line);
2564 else
2565 error (_("Cannot find a good line."));
2566 }
2567 }
2568 else
2569 /* Is there any case in which we get here, and have an address
2570 which the user would want to see? If we have debugging
2571 symbols and no line numbers? */
2572 error (_("Line number %d is out of range for \"%s\"."),
05cba821 2573 sal.line, symtab_to_filename_for_display (sal.symtab));
35b1e5cc
SS
2574
2575 /* Find within range of stated line. */
2576 if (args && *args)
f197e0f1 2577 tfind_1 (tfind_range, 0, start_pc, end_pc - 1, from_tty);
c906108c 2578 else
f197e0f1 2579 tfind_1 (tfind_outside, 0, start_pc, end_pc - 1, from_tty);
35b1e5cc 2580 do_cleanups (old_chain);
c906108c
SS
2581}
2582
2583/* tfind range command */
2584static void
fba45db2 2585trace_find_range_command (char *args, int from_tty)
104c1213 2586{
c906108c
SS
2587 static CORE_ADDR start, stop;
2588 char *tmp;
2589
f5911ea1
HAQ
2590 if (current_trace_status ()->running
2591 && current_trace_status ()->filename == NULL)
a73c6dcd 2592 error (_("May not look at trace frames while trace is running."));
c906108c 2593
35b1e5cc
SS
2594 if (args == 0 || *args == 0)
2595 { /* XXX FIXME: what should default behavior be? */
2596 printf_filtered ("Usage: tfind range <startaddr>,<endaddr>\n");
2597 return;
2598 }
c906108c 2599
35b1e5cc
SS
2600 if (0 != (tmp = strchr (args, ',')))
2601 {
c378eb4e 2602 *tmp++ = '\0'; /* Terminate start address. */
529480d0 2603 tmp = skip_spaces (tmp);
35b1e5cc
SS
2604 start = parse_and_eval_address (args);
2605 stop = parse_and_eval_address (tmp);
c906108c
SS
2606 }
2607 else
c378eb4e 2608 { /* No explicit end address? */
35b1e5cc
SS
2609 start = parse_and_eval_address (args);
2610 stop = start + 1; /* ??? */
2611 }
2612
f197e0f1 2613 tfind_1 (tfind_range, 0, start, stop, from_tty);
c906108c
SS
2614}
2615
2616/* tfind outside command */
2617static void
fba45db2 2618trace_find_outside_command (char *args, int from_tty)
104c1213 2619{
c906108c
SS
2620 CORE_ADDR start, stop;
2621 char *tmp;
2622
f5911ea1
HAQ
2623 if (current_trace_status ()->running
2624 && current_trace_status ()->filename == NULL)
a73c6dcd 2625 error (_("May not look at trace frames while trace is running."));
c906108c 2626
35b1e5cc 2627 if (args == 0 || *args == 0)
c378eb4e 2628 { /* XXX FIXME: what should default behavior be? */
35b1e5cc
SS
2629 printf_filtered ("Usage: tfind outside <startaddr>,<endaddr>\n");
2630 return;
2631 }
c906108c 2632
35b1e5cc
SS
2633 if (0 != (tmp = strchr (args, ',')))
2634 {
c378eb4e 2635 *tmp++ = '\0'; /* Terminate start address. */
529480d0 2636 tmp = skip_spaces (tmp);
35b1e5cc
SS
2637 start = parse_and_eval_address (args);
2638 stop = parse_and_eval_address (tmp);
c906108c
SS
2639 }
2640 else
c378eb4e 2641 { /* No explicit end address? */
35b1e5cc
SS
2642 start = parse_and_eval_address (args);
2643 stop = start + 1; /* ??? */
2644 }
2645
f197e0f1 2646 tfind_1 (tfind_outside, 0, start, stop, from_tty);
c906108c
SS
2647}
2648
c906108c
SS
2649/* info scope command: list the locals for a scope. */
2650static void
fba45db2 2651scope_info (char *args, int from_tty)
c906108c 2652{
c906108c
SS
2653 struct symtabs_and_lines sals;
2654 struct symbol *sym;
2655 struct minimal_symbol *msym;
2656 struct block *block;
0d5cff50
DE
2657 const char *symname;
2658 char *save_args = args;
8157b174 2659 struct block_iterator iter;
de4f826b 2660 int j, count = 0;
768a979c
UW
2661 struct gdbarch *gdbarch;
2662 int regno;
c906108c
SS
2663
2664 if (args == 0 || *args == 0)
3e43a32a
MS
2665 error (_("requires an argument (function, "
2666 "line or *addr) to define a scope"));
c906108c 2667
f8eba3c6 2668 sals = decode_line_1 (&args, DECODE_LINE_FUNFIRSTLINE, NULL, 0);
c906108c 2669 if (sals.nelts == 0)
c378eb4e 2670 return; /* Presumably decode_line_1 has already warned. */
c906108c 2671
c378eb4e 2672 /* Resolve line numbers to PC. */
c906108c
SS
2673 resolve_sal_pc (&sals.sals[0]);
2674 block = block_for_pc (sals.sals[0].pc);
2675
2676 while (block != 0)
2677 {
c378eb4e 2678 QUIT; /* Allow user to bail out with ^C. */
de4f826b 2679 ALL_BLOCK_SYMBOLS (block, iter, sym)
c906108c 2680 {
c378eb4e 2681 QUIT; /* Allow user to bail out with ^C. */
c906108c
SS
2682 if (count == 0)
2683 printf_filtered ("Scope for %s:\n", save_args);
2684 count++;
e88c90f2 2685
3567439c 2686 symname = SYMBOL_PRINT_NAME (sym);
c906108c 2687 if (symname == NULL || *symname == '\0')
c378eb4e 2688 continue; /* Probably botched, certainly useless. */
c906108c 2689
768a979c
UW
2690 gdbarch = get_objfile_arch (SYMBOL_SYMTAB (sym)->objfile);
2691
c906108c 2692 printf_filtered ("Symbol %s is ", symname);
24d6c2a0
TT
2693
2694 if (SYMBOL_COMPUTED_OPS (sym) != NULL)
2695 SYMBOL_COMPUTED_OPS (sym)->describe_location (sym,
2696 BLOCK_START (block),
2697 gdb_stdout);
2698 else
c5aa993b 2699 {
24d6c2a0 2700 switch (SYMBOL_CLASS (sym))
c5aa993b 2701 {
24d6c2a0
TT
2702 default:
2703 case LOC_UNDEF: /* Messed up symbol? */
2704 printf_filtered ("a bogus symbol, class %d.\n",
2705 SYMBOL_CLASS (sym));
2706 count--; /* Don't count this one. */
2707 continue;
2708 case LOC_CONST:
2709 printf_filtered ("a constant with value %s (%s)",
2710 plongest (SYMBOL_VALUE (sym)),
2711 hex_string (SYMBOL_VALUE (sym)));
2712 break;
2713 case LOC_CONST_BYTES:
2714 printf_filtered ("constant bytes: ");
2715 if (SYMBOL_TYPE (sym))
2716 for (j = 0; j < TYPE_LENGTH (SYMBOL_TYPE (sym)); j++)
2717 fprintf_filtered (gdb_stdout, " %02x",
2718 (unsigned) SYMBOL_VALUE_BYTES (sym)[j]);
2719 break;
2720 case LOC_STATIC:
2721 printf_filtered ("in static storage at address ");
2722 printf_filtered ("%s", paddress (gdbarch,
2723 SYMBOL_VALUE_ADDRESS (sym)));
2724 break;
2725 case LOC_REGISTER:
2726 /* GDBARCH is the architecture associated with the objfile
2727 the symbol is defined in; the target architecture may be
2728 different, and may provide additional registers. However,
2729 we do not know the target architecture at this point.
2730 We assume the objfile architecture will contain all the
2731 standard registers that occur in debug info in that
2732 objfile. */
2733 regno = SYMBOL_REGISTER_OPS (sym)->register_number (sym,
2734 gdbarch);
2735
2736 if (SYMBOL_IS_ARGUMENT (sym))
2737 printf_filtered ("an argument in register $%s",
2738 gdbarch_register_name (gdbarch, regno));
2739 else
2740 printf_filtered ("a local variable in register $%s",
2741 gdbarch_register_name (gdbarch, regno));
2742 break;
2743 case LOC_ARG:
2744 printf_filtered ("an argument at stack/frame offset %s",
2745 plongest (SYMBOL_VALUE (sym)));
2746 break;
2747 case LOC_LOCAL:
2748 printf_filtered ("a local variable at frame offset %s",
2749 plongest (SYMBOL_VALUE (sym)));
2750 break;
2751 case LOC_REF_ARG:
2752 printf_filtered ("a reference argument at offset %s",
2753 plongest (SYMBOL_VALUE (sym)));
2754 break;
2755 case LOC_REGPARM_ADDR:
2756 /* Note comment at LOC_REGISTER. */
2757 regno = SYMBOL_REGISTER_OPS (sym)->register_number (sym,
2758 gdbarch);
2759 printf_filtered ("the address of an argument, in register $%s",
2760 gdbarch_register_name (gdbarch, regno));
2761 break;
2762 case LOC_TYPEDEF:
2763 printf_filtered ("a typedef.\n");
2764 continue;
2765 case LOC_LABEL:
2766 printf_filtered ("a label at address ");
2767 printf_filtered ("%s", paddress (gdbarch,
2768 SYMBOL_VALUE_ADDRESS (sym)));
2769 break;
2770 case LOC_BLOCK:
2771 printf_filtered ("a function at address ");
5af949e3 2772 printf_filtered ("%s",
24d6c2a0
TT
2773 paddress (gdbarch, BLOCK_START (SYMBOL_BLOCK_VALUE (sym))));
2774 break;
2775 case LOC_UNRESOLVED:
2776 msym = lookup_minimal_symbol (SYMBOL_LINKAGE_NAME (sym),
2777 NULL, NULL);
2778 if (msym == NULL)
2779 printf_filtered ("Unresolved Static");
2780 else
2781 {
2782 printf_filtered ("static storage at address ");
2783 printf_filtered ("%s",
2784 paddress (gdbarch,
2785 SYMBOL_VALUE_ADDRESS (msym)));
2786 }
2787 break;
2788 case LOC_OPTIMIZED_OUT:
2789 printf_filtered ("optimized out.\n");
2790 continue;
2791 case LOC_COMPUTED:
2792 gdb_assert_not_reached (_("LOC_COMPUTED variable missing a method"));
c5aa993b 2793 }
c5aa993b 2794 }
c906108c 2795 if (SYMBOL_TYPE (sym))
c5aa993b 2796 printf_filtered (", length %d.\n",
450bd37b 2797 TYPE_LENGTH (check_typedef (SYMBOL_TYPE (sym))));
c906108c
SS
2798 }
2799 if (BLOCK_FUNCTION (block))
2800 break;
2801 else
2802 block = BLOCK_SUPERBLOCK (block);
2803 }
2804 if (count <= 0)
2805 printf_filtered ("Scope for %s contains no locals or arguments.\n",
2806 save_args);
2807}
2808
afd02f27
PA
2809/* Helper for trace_dump_command. Dump the action list starting at
2810 ACTION. STEPPING_ACTIONS is true if we're iterating over the
2811 actions of the body of a while-stepping action. STEPPING_FRAME is
2812 set if the current traceframe was determined to be a while-stepping
2813 traceframe. */
2814
c906108c 2815static void
afd02f27
PA
2816trace_dump_actions (struct command_line *action,
2817 int stepping_actions, int stepping_frame,
2818 int from_tty)
c906108c 2819{
6f937416 2820 const char *action_exp, *next_comma;
c906108c 2821
afd02f27 2822 for (; action != NULL; action = action->next)
c906108c
SS
2823 {
2824 struct cmd_list_element *cmd;
2825
c378eb4e 2826 QUIT; /* Allow user to bail out with ^C. */
a7bdde9e 2827 action_exp = action->line;
6f937416 2828 action_exp = skip_spaces_const (action_exp);
c906108c
SS
2829
2830 /* The collection actions to be done while stepping are
c5aa993b 2831 bracketed by the commands "while-stepping" and "end". */
c906108c
SS
2832
2833 if (*action_exp == '#') /* comment line */
2834 continue;
2835
2836 cmd = lookup_cmd (&action_exp, cmdlist, "", -1, 1);
2837 if (cmd == 0)
8a3fe4f8 2838 error (_("Bad action list item: %s"), action_exp);
c906108c 2839
bbaca940 2840 if (cmd_cfunc_eq (cmd, while_stepping_pseudocommand))
afd02f27
PA
2841 {
2842 int i;
2843
2844 for (i = 0; i < action->body_count; ++i)
2845 trace_dump_actions (action->body_list[i],
2846 1, stepping_frame, from_tty);
2847 }
bbaca940 2848 else if (cmd_cfunc_eq (cmd, collect_pseudocommand))
c906108c
SS
2849 {
2850 /* Display the collected data.
d183932d
MS
2851 For the trap frame, display only what was collected at
2852 the trap. Likewise for stepping frames, display only
2853 what was collected while stepping. This means that the
2854 two boolean variables, STEPPING_FRAME and
2855 STEPPING_ACTIONS should be equal. */
c906108c
SS
2856 if (stepping_frame == stepping_actions)
2857 {
6f937416
PA
2858 char *cmd = NULL;
2859 struct cleanup *old_chain
2860 = make_cleanup (free_current_contents, &cmd);
92bc6a20 2861 int trace_string = 0;
6f937416 2862
3065dfb6 2863 if (*action_exp == '/')
92bc6a20 2864 action_exp = decode_agent_options (action_exp, &trace_string);
3065dfb6 2865
c5aa993b 2866 do
c378eb4e
MS
2867 { /* Repeat over a comma-separated list. */
2868 QUIT; /* Allow user to bail out with ^C. */
c5aa993b
JM
2869 if (*action_exp == ',')
2870 action_exp++;
6f937416 2871 action_exp = skip_spaces_const (action_exp);
c5aa993b
JM
2872
2873 next_comma = strchr (action_exp, ',');
2874
2875 if (0 == strncasecmp (action_exp, "$reg", 4))
2876 registers_info (NULL, from_tty);
6710bf39
SS
2877 else if (0 == strncasecmp (action_exp, "$_ret", 5))
2878 ;
c5aa993b
JM
2879 else if (0 == strncasecmp (action_exp, "$loc", 4))
2880 locals_info (NULL, from_tty);
2881 else if (0 == strncasecmp (action_exp, "$arg", 4))
2882 args_info (NULL, from_tty);
2883 else
2884 { /* variable */
6f937416 2885 if (next_comma != NULL)
c5aa993b 2886 {
6f937416
PA
2887 size_t len = next_comma - action_exp;
2888
2889 cmd = xrealloc (cmd, len + 1);
2890 memcpy (cmd, action_exp, len);
2891 cmd[len] = 0;
2892 }
2893 else
2894 {
2895 size_t len = strlen (action_exp);
2896
2897 cmd = xrealloc (cmd, len + 1);
2898 memcpy (cmd, action_exp, len + 1);
c5aa993b 2899 }
6f937416
PA
2900
2901 printf_filtered ("%s = ", cmd);
2902 output_command_const (cmd, from_tty);
c5aa993b
JM
2903 printf_filtered ("\n");
2904 }
c5aa993b
JM
2905 action_exp = next_comma;
2906 }
2907 while (action_exp && *action_exp == ',');
6f937416
PA
2908
2909 do_cleanups (old_chain);
c906108c
SS
2910 }
2911 }
2912 }
afd02f27
PA
2913}
2914
2915/* The tdump command. */
2916
2917static void
2918trace_dump_command (char *args, int from_tty)
2919{
2920 struct regcache *regcache;
d9b3f62e 2921 struct tracepoint *t;
afd02f27
PA
2922 int stepping_frame = 0;
2923 struct bp_location *loc;
6f937416 2924 char *default_collect_line = NULL;
2114d44c 2925 struct command_line *actions, *default_collect_action = NULL;
4fd2d6af 2926 struct cleanup *old_chain;
afd02f27
PA
2927
2928 if (tracepoint_number == -1)
2929 {
2930 warning (_("No current trace frame."));
2931 return;
2932 }
2933
4fd2d6af 2934 old_chain = make_cleanup (null_cleanup, NULL);
afd02f27
PA
2935 t = get_tracepoint (tracepoint_number);
2936
2937 if (t == NULL)
2938 error (_("No known tracepoint matches 'current' tracepoint #%d."),
2939 tracepoint_number);
2940
2941 printf_filtered ("Data collected at tracepoint %d, trace frame %d:\n",
2942 tracepoint_number, traceframe_number);
2943
2944 /* The current frame is a trap frame if the frame PC is equal
2945 to the tracepoint PC. If not, then the current frame was
2946 collected during single-stepping. */
2947
2948 regcache = get_current_regcache ();
2949
2950 /* If the traceframe's address matches any of the tracepoint's
2951 locations, assume it is a direct hit rather than a while-stepping
2952 frame. (FIXME this is not reliable, should record each frame's
2953 type.) */
2954 stepping_frame = 1;
d9b3f62e 2955 for (loc = t->base.loc; loc; loc = loc->next)
afd02f27
PA
2956 if (loc->address == regcache_read_pc (regcache))
2957 stepping_frame = 0;
2958
d9b3f62e 2959 actions = breakpoint_commands (&t->base);
2114d44c
SS
2960
2961 /* If there is a default-collect list, make up a collect command,
2962 prepend to the tracepoint's commands, and pass the whole mess to
2963 the trace dump scanner. We need to validate because
2964 default-collect might have been junked since the trace run. */
2965 if (*default_collect)
2966 {
2967 default_collect_line = xstrprintf ("collect %s", default_collect);
4fd2d6af 2968 make_cleanup (xfree, default_collect_line);
6f937416 2969 validate_actionline (default_collect_line, &t->base);
2114d44c
SS
2970 default_collect_action = xmalloc (sizeof (struct command_line));
2971 make_cleanup (xfree, default_collect_action);
2972 default_collect_action->next = actions;
6f937416 2973 default_collect_action->line = default_collect_line;
2114d44c
SS
2974 actions = default_collect_action;
2975 }
2976
2977 trace_dump_actions (actions, 0, stepping_frame, from_tty);
2978
4fd2d6af 2979 do_cleanups (old_chain);
c906108c
SS
2980}
2981
409873ef
SS
2982/* Encode a piece of a tracepoint's source-level definition in a form
2983 that is suitable for both protocol and saving in files. */
2984/* This version does not do multiple encodes for long strings; it should
2985 return an offset to the next piece to encode. FIXME */
2986
2987extern int
2988encode_source_string (int tpnum, ULONGEST addr,
2989 char *srctype, char *src, char *buf, int buf_size)
2990{
2991 if (80 + strlen (srctype) > buf_size)
2992 error (_("Buffer too small for source encoding"));
2993 sprintf (buf, "%x:%s:%s:%x:%x:",
3e43a32a
MS
2994 tpnum, phex_nz (addr, sizeof (addr)),
2995 srctype, 0, (int) strlen (src));
409873ef
SS
2996 if (strlen (buf) + strlen (src) * 2 >= buf_size)
2997 error (_("Source string too long for buffer"));
bc20a4af 2998 bin2hex ((gdb_byte *) src, buf + strlen (buf), 0);
409873ef
SS
2999 return -1;
3000}
3001
3f43bc09 3002/* Free trace file writer. */
00bf0b85 3003
3f43bc09
YQ
3004static void
3005trace_file_writer_xfree (void *arg)
3006{
3007 struct trace_file_writer *writer = arg;
011aacb0 3008
3f43bc09
YQ
3009 writer->ops->dtor (writer);
3010 xfree (writer);
3011}
3012
3013/* TFILE trace writer. */
3014
3015struct tfile_trace_file_writer
00bf0b85 3016{
3f43bc09
YQ
3017 struct trace_file_writer base;
3018
3019 /* File pointer to tfile trace file. */
00bf0b85 3020 FILE *fp;
3f43bc09
YQ
3021 /* Path name of the tfile trace file. */
3022 char *pathname;
3023};
00bf0b85 3024
3f43bc09
YQ
3025/* This is the implementation of trace_file_write_ops method
3026 target_save. We just call the generic target
3027 target_save_trace_data to do target-side saving. */
00bf0b85 3028
3f43bc09
YQ
3029static int
3030tfile_target_save (struct trace_file_writer *self,
3031 const char *filename)
3032{
3033 int err = target_save_trace_data (filename);
3034
3035 return (err >= 0);
3036}
3037
3038/* This is the implementation of trace_file_write_ops method
3039 dtor. */
3040
3041static void
3042tfile_dtor (struct trace_file_writer *self)
3043{
3044 struct tfile_trace_file_writer *writer
3045 = (struct tfile_trace_file_writer *) self;
3046
3047 xfree (writer->pathname);
00bf0b85 3048
3f43bc09
YQ
3049 if (writer->fp != NULL)
3050 fclose (writer->fp);
3051}
3052
3053/* This is the implementation of trace_file_write_ops method
3054 start. It creates the trace file FILENAME and registers some
3055 cleanups. */
00bf0b85 3056
3f43bc09
YQ
3057static void
3058tfile_start (struct trace_file_writer *self, const char *filename)
3059{
3060 struct tfile_trace_file_writer *writer
3061 = (struct tfile_trace_file_writer *) self;
3062
3063 writer->pathname = tilde_expand (filename);
614c279d 3064 writer->fp = gdb_fopen_cloexec (writer->pathname, "wb");
3f43bc09 3065 if (writer->fp == NULL)
00bf0b85 3066 error (_("Unable to open file '%s' for saving trace data (%s)"),
011aacb0 3067 filename, safe_strerror (errno));
3f43bc09
YQ
3068}
3069
3070/* This is the implementation of trace_file_write_ops method
3071 write_header. Write the TFILE header. */
3072
3073static void
3074tfile_write_header (struct trace_file_writer *self)
3075{
3076 struct tfile_trace_file_writer *writer
3077 = (struct tfile_trace_file_writer *) self;
3078 int written;
00bf0b85
SS
3079
3080 /* Write a file header, with a high-bit-set char to indicate a
3081 binary file, plus a hint as what this file is, and a version
3082 number in case of future needs. */
3f43bc09 3083 written = fwrite ("\x7fTRACE0\n", 8, 1, writer->fp);
409873ef 3084 if (written < 1)
3f43bc09
YQ
3085 perror_with_name (writer->pathname);
3086}
00bf0b85 3087
3f43bc09
YQ
3088/* This is the implementation of trace_file_write_ops method
3089 write_regblock_type. Write the size of register block. */
00bf0b85 3090
3f43bc09
YQ
3091static void
3092tfile_write_regblock_type (struct trace_file_writer *self, int size)
3093{
3094 struct tfile_trace_file_writer *writer
3095 = (struct tfile_trace_file_writer *) self;
00bf0b85 3096
3f43bc09
YQ
3097 fprintf (writer->fp, "R %x\n", size);
3098}
3099
3100/* This is the implementation of trace_file_write_ops method
3101 write_status. */
3102
3103static void
3104tfile_write_status (struct trace_file_writer *self,
3105 struct trace_status *ts)
3106{
3107 struct tfile_trace_file_writer *writer
3108 = (struct tfile_trace_file_writer *) self;
3109
3110 fprintf (writer->fp, "status %c;%s",
6c28cbf2 3111 (ts->running ? '1' : '0'), stop_reason_names[ts->stop_reason]);
d6682f9e
YQ
3112 if (ts->stop_reason == tracepoint_error
3113 || ts->stop_reason == tstop_command)
6c28cbf2 3114 {
f196051f 3115 char *buf = (char *) alloca (strlen (ts->stop_desc) * 2 + 1);
5d502164 3116
f196051f 3117 bin2hex ((gdb_byte *) ts->stop_desc, buf, 0);
3f43bc09 3118 fprintf (writer->fp, ":%s", buf);
6c28cbf2 3119 }
3f43bc09 3120 fprintf (writer->fp, ":%x", ts->stopping_tracepoint);
4daf5ac0 3121 if (ts->traceframe_count >= 0)
3f43bc09 3122 fprintf (writer->fp, ";tframes:%x", ts->traceframe_count);
4daf5ac0 3123 if (ts->traceframes_created >= 0)
3f43bc09 3124 fprintf (writer->fp, ";tcreated:%x", ts->traceframes_created);
4daf5ac0 3125 if (ts->buffer_free >= 0)
3f43bc09 3126 fprintf (writer->fp, ";tfree:%x", ts->buffer_free);
4daf5ac0 3127 if (ts->buffer_size >= 0)
3f43bc09 3128 fprintf (writer->fp, ";tsize:%x", ts->buffer_size);
33da3f1c 3129 if (ts->disconnected_tracing)
3f43bc09 3130 fprintf (writer->fp, ";disconn:%x", ts->disconnected_tracing);
33da3f1c 3131 if (ts->circular_buffer)
3f43bc09 3132 fprintf (writer->fp, ";circular:%x", ts->circular_buffer);
a22fa6e4
YQ
3133 if (ts->notes != NULL)
3134 {
3135 char *buf = (char *) alloca (strlen (ts->notes) * 2 + 1);
3136
3137 bin2hex ((gdb_byte *) ts->notes, buf, 0);
3138 fprintf (writer->fp, ";notes:%s", buf);
3139 }
3140 if (ts->user_name != NULL)
3141 {
3142 char *buf = (char *) alloca (strlen (ts->user_name) * 2 + 1);
3143
3144 bin2hex ((gdb_byte *) ts->user_name, buf, 0);
3145 fprintf (writer->fp, ";username:%s", buf);
3146 }
3f43bc09
YQ
3147 fprintf (writer->fp, "\n");
3148}
3149
3150/* This is the implementation of trace_file_write_ops method
3151 write_uploaded_tsv. */
3152
3153static void
3154tfile_write_uploaded_tsv (struct trace_file_writer *self,
3155 struct uploaded_tsv *utsv)
3156{
3157 char *buf = "";
3158 struct tfile_trace_file_writer *writer
3159 = (struct tfile_trace_file_writer *) self;
3160
3161 if (utsv->name)
3162 {
3163 buf = (char *) xmalloc (strlen (utsv->name) * 2 + 1);
3164 bin2hex ((gdb_byte *) (utsv->name), buf, 0);
3165 }
3166
3167 fprintf (writer->fp, "tsv %x:%s:%x:%s\n",
3168 utsv->number, phex_nz (utsv->initial_value, 8),
3169 utsv->builtin, buf);
3170
3171 if (utsv->name)
3172 xfree (buf);
3173}
3174
3175#define MAX_TRACE_UPLOAD 2000
3176
3177/* This is the implementation of trace_file_write_ops method
3178 write_uploaded_tp. */
3179
3180static void
3181tfile_write_uploaded_tp (struct trace_file_writer *self,
3182 struct uploaded_tp *utp)
3183{
3184 struct tfile_trace_file_writer *writer
3185 = (struct tfile_trace_file_writer *) self;
3186 int a;
3187 char *act;
bc20a4af 3188 char buf[MAX_TRACE_UPLOAD];
3f43bc09
YQ
3189
3190 fprintf (writer->fp, "tp T%x:%s:%c:%x:%x",
3191 utp->number, phex_nz (utp->addr, sizeof (utp->addr)),
3192 (utp->enabled ? 'E' : 'D'), utp->step, utp->pass);
3193 if (utp->type == bp_fast_tracepoint)
3194 fprintf (writer->fp, ":F%x", utp->orig_size);
3195 if (utp->cond)
3196 fprintf (writer->fp,
3197 ":X%x,%s", (unsigned int) strlen (utp->cond) / 2,
3198 utp->cond);
3199 fprintf (writer->fp, "\n");
3200 for (a = 0; VEC_iterate (char_ptr, utp->actions, a, act); ++a)
3201 fprintf (writer->fp, "tp A%x:%s:%s\n",
3202 utp->number, phex_nz (utp->addr, sizeof (utp->addr)), act);
3203 for (a = 0; VEC_iterate (char_ptr, utp->step_actions, a, act); ++a)
3204 fprintf (writer->fp, "tp S%x:%s:%s\n",
3205 utp->number, phex_nz (utp->addr, sizeof (utp->addr)), act);
3206 if (utp->at_string)
3207 {
3208 encode_source_string (utp->number, utp->addr,
3209 "at", utp->at_string, buf, MAX_TRACE_UPLOAD);
3210 fprintf (writer->fp, "tp Z%s\n", buf);
3211 }
3212 if (utp->cond_string)
3213 {
3214 encode_source_string (utp->number, utp->addr,
3215 "cond", utp->cond_string,
3216 buf, MAX_TRACE_UPLOAD);
3217 fprintf (writer->fp, "tp Z%s\n", buf);
3218 }
3219 for (a = 0; VEC_iterate (char_ptr, utp->cmd_strings, a, act); ++a)
3220 {
3221 encode_source_string (utp->number, utp->addr, "cmd", act,
3222 buf, MAX_TRACE_UPLOAD);
3223 fprintf (writer->fp, "tp Z%s\n", buf);
3224 }
3225 fprintf (writer->fp, "tp V%x:%s:%x:%s\n",
3226 utp->number, phex_nz (utp->addr, sizeof (utp->addr)),
3227 utp->hit_count,
3228 phex_nz (utp->traceframe_usage,
3229 sizeof (utp->traceframe_usage)));
3230}
3231
3232/* This is the implementation of trace_file_write_ops method
3233 write_definition_end. */
3234
3235static void
3236tfile_write_definition_end (struct trace_file_writer *self)
3237{
3238 struct tfile_trace_file_writer *writer
3239 = (struct tfile_trace_file_writer *) self;
3240
3241 fprintf (writer->fp, "\n");
3242}
3243
3244/* This is the implementation of trace_file_write_ops method
3245 write_raw_data. */
3246
3247static void
3248tfile_write_raw_data (struct trace_file_writer *self, gdb_byte *buf,
3249 LONGEST len)
3250{
3251 struct tfile_trace_file_writer *writer
3252 = (struct tfile_trace_file_writer *) self;
3253
3254 if (fwrite (buf, len, 1, writer->fp) < 1)
3255 perror_with_name (writer->pathname);
3256}
3257
3258/* This is the implementation of trace_file_write_ops method
3259 end. */
3260
3261static void
3262tfile_end (struct trace_file_writer *self)
3263{
3264 struct tfile_trace_file_writer *writer
3265 = (struct tfile_trace_file_writer *) self;
3266 uint32_t gotten = 0;
3267
3268 /* Mark the end of trace data. */
3269 if (fwrite (&gotten, 4, 1, writer->fp) < 1)
3270 perror_with_name (writer->pathname);
3271}
3272
3273/* Operations to write trace buffers into TFILE format. */
3274
3275static const struct trace_file_write_ops tfile_write_ops =
3276{
3277 tfile_dtor,
3278 tfile_target_save,
3279 tfile_start,
3280 tfile_write_header,
3281 tfile_write_regblock_type,
3282 tfile_write_status,
3283 tfile_write_uploaded_tsv,
3284 tfile_write_uploaded_tp,
3285 tfile_write_definition_end,
3286 tfile_write_raw_data,
3287 NULL,
3288 tfile_end,
3289};
3290
3291/* Helper macros. */
3292
3293#define TRACE_WRITE_R_BLOCK(writer, buf, size) \
3294 writer->ops->frame_ops->write_r_block ((writer), (buf), (size))
3295#define TRACE_WRITE_M_BLOCK_HEADER(writer, addr, size) \
3296 writer->ops->frame_ops->write_m_block_header ((writer), (addr), \
3297 (size))
3298#define TRACE_WRITE_M_BLOCK_MEMORY(writer, buf, size) \
3299 writer->ops->frame_ops->write_m_block_memory ((writer), (buf), \
3300 (size))
3301#define TRACE_WRITE_V_BLOCK(writer, num, val) \
3302 writer->ops->frame_ops->write_v_block ((writer), (num), (val))
3303
3f43bc09
YQ
3304/* Save tracepoint data to file named FILENAME through WRITER. WRITER
3305 determines the trace file format. If TARGET_DOES_SAVE is non-zero,
3306 the save is performed on the target, otherwise GDB obtains all trace
3307 data and saves it locally. */
3308
3309static void
3310trace_save (const char *filename, struct trace_file_writer *writer,
3311 int target_does_save)
3312{
3313 struct trace_status *ts = current_trace_status ();
3314 int status;
3315 struct uploaded_tp *uploaded_tps = NULL, *utp;
3316 struct uploaded_tsv *uploaded_tsvs = NULL, *utsv;
3317
3318 ULONGEST offset = 0;
3319 gdb_byte buf[MAX_TRACE_UPLOAD];
bc20a4af 3320#define MAX_TRACE_UPLOAD 2000
3f43bc09
YQ
3321 int written;
3322 enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch ());
3323
3324 /* If the target is to save the data to a file on its own, then just
3325 send the command and be done with it. */
3326 if (target_does_save)
3327 {
3328 if (!writer->ops->target_save (writer, filename))
3329 error (_("Target failed to save trace data to '%s'."),
3330 filename);
3331 return;
3332 }
3333
3334 /* Get the trace status first before opening the file, so if the
3335 target is losing, we can get out without touching files. */
3336 status = target_get_trace_status (ts);
3337
3cf62c1d
KS
3338 writer->ops->start (writer, filename);
3339
3f43bc09
YQ
3340 writer->ops->write_header (writer);
3341
3342 /* Write descriptive info. */
3343
3344 /* Write out the size of a register block. */
3345 writer->ops->write_regblock_type (writer, trace_regblock_size);
3346
3347 /* Write out status of the tracing run (aka "tstatus" info). */
3348 writer->ops->write_status (writer, ts);
00bf0b85
SS
3349
3350 /* Note that we want to upload tracepoints and save those, rather
3351 than simply writing out the local ones, because the user may have
3352 changed tracepoints in GDB in preparation for a future tracing
3353 run, or maybe just mass-deleted all types of breakpoints as part
3354 of cleaning up. So as not to contaminate the session, leave the
3355 data in its uploaded form, don't make into real tracepoints. */
3356
3357 /* Get trace state variables first, they may be checked when parsing
3358 uploaded commands. */
3359
3360 target_upload_trace_state_variables (&uploaded_tsvs);
3361
3362 for (utsv = uploaded_tsvs; utsv; utsv = utsv->next)
3f43bc09 3363 writer->ops->write_uploaded_tsv (writer, utsv);
00bf0b85
SS
3364
3365 free_uploaded_tsvs (&uploaded_tsvs);
3366
3367 target_upload_tracepoints (&uploaded_tps);
3368
f196051f
SS
3369 for (utp = uploaded_tps; utp; utp = utp->next)
3370 target_get_tracepoint_status (NULL, utp);
3371
00bf0b85 3372 for (utp = uploaded_tps; utp; utp = utp->next)
3f43bc09
YQ
3373 writer->ops->write_uploaded_tp (writer, utp);
3374
3375 free_uploaded_tps (&uploaded_tps);
3376
3377 /* Mark the end of the definition section. */
3378 writer->ops->write_definition_end (writer);
3379
3380 /* Get and write the trace data proper. */
3381 while (1)
00bf0b85 3382 {
3f43bc09
YQ
3383 LONGEST gotten = 0;
3384
3385 /* The writer supports writing the contents of trace buffer
3386 directly to trace file. Don't parse the contents of trace
3387 buffer. */
3388 if (writer->ops->write_trace_buffer != NULL)
409873ef 3389 {
3f43bc09
YQ
3390 /* We ask for big blocks, in the hopes of efficiency, but
3391 will take less if the target has packet size limitations
3392 or some such. */
3393 gotten = target_get_raw_trace_data (buf, offset,
3394 MAX_TRACE_UPLOAD);
3395 if (gotten < 0)
3396 error (_("Failure to get requested trace buffer data"));
3397 /* No more data is forthcoming, we're done. */
3398 if (gotten == 0)
3399 break;
3400
3401 writer->ops->write_trace_buffer (writer, buf, gotten);
3402
3403 offset += gotten;
409873ef 3404 }
3f43bc09 3405 else
409873ef 3406 {
3f43bc09
YQ
3407 uint16_t tp_num;
3408 uint32_t tf_size;
3409 /* Parse the trace buffers according to how data are stored
3410 in trace buffer in GDBserver. */
3411
3412 gotten = target_get_raw_trace_data (buf, offset, 6);
3413
3414 if (gotten == 0)
3415 break;
3416
3417 /* Read the first six bytes in, which is the tracepoint
3418 number and trace frame size. */
3419 tp_num = (uint16_t)
3420 extract_unsigned_integer (&buf[0], 2, byte_order);
3421
3422 tf_size = (uint32_t)
3423 extract_unsigned_integer (&buf[2], 4, byte_order);
3424
3425 writer->ops->frame_ops->start (writer, tp_num);
3426 gotten = 6;
3427
3428 if (tf_size > 0)
3429 {
3430 unsigned int block;
3431
3432 offset += 6;
3433
3434 for (block = 0; block < tf_size; )
3435 {
3436 gdb_byte block_type;
3437
3438 /* We'll fetch one block each time, in order to
3439 handle the extremely large 'M' block. We first
3440 fetch one byte to get the type of the block. */
3441 gotten = target_get_raw_trace_data (buf, offset, 1);
3442 if (gotten < 1)
3443 error (_("Failure to get requested trace buffer data"));
3444
3445 gotten = 1;
3446 block += 1;
3447 offset += 1;
3448
3449 block_type = buf[0];
3450 switch (block_type)
3451 {
3452 case 'R':
3453 gotten
3454 = target_get_raw_trace_data (buf, offset,
3455 trace_regblock_size);
3456 if (gotten < trace_regblock_size)
3457 error (_("Failure to get requested trace"
3458 " buffer data"));
3459
3460 TRACE_WRITE_R_BLOCK (writer, buf,
3461 trace_regblock_size);
3462 break;
3463 case 'M':
3464 {
3465 unsigned short mlen;
3466 ULONGEST addr;
3467 LONGEST t;
3468 int j;
3469
3470 t = target_get_raw_trace_data (buf,offset, 10);
3471 if (t < 10)
3472 error (_("Failure to get requested trace"
3473 " buffer data"));
3474
3475 offset += 10;
3476 block += 10;
3477
3478 gotten = 0;
3479 addr = (ULONGEST)
3480 extract_unsigned_integer (buf, 8,
3481 byte_order);
3482 mlen = (unsigned short)
3483 extract_unsigned_integer (&buf[8], 2,
3484 byte_order);
3485
3486 TRACE_WRITE_M_BLOCK_HEADER (writer, addr,
3487 mlen);
3488
3489 /* The memory contents in 'M' block may be
3490 very large. Fetch the data from the target
3491 and write them into file one by one. */
3492 for (j = 0; j < mlen; )
3493 {
3494 unsigned int read_length;
3495
3496 if (mlen - j > MAX_TRACE_UPLOAD)
3497 read_length = MAX_TRACE_UPLOAD;
3498 else
3499 read_length = mlen - j;
3500
3501 t = target_get_raw_trace_data (buf,
3502 offset + j,
3503 read_length);
3504 if (t < read_length)
3505 error (_("Failure to get requested"
3506 " trace buffer data"));
3507
3508 TRACE_WRITE_M_BLOCK_MEMORY (writer, buf,
3509 read_length);
3510
3511 j += read_length;
3512 gotten += read_length;
3513 }
3514
3515 break;
3516 }
3517 case 'V':
3518 {
3519 int vnum;
3520 LONGEST val;
3521
3522 gotten
3523 = target_get_raw_trace_data (buf, offset,
3524 12);
3525 if (gotten < 12)
3526 error (_("Failure to get requested"
3527 " trace buffer data"));
3528
3529 vnum = (int) extract_signed_integer (buf,
3530 4,
3531 byte_order);
3532 val
3533 = extract_signed_integer (&buf[4], 8,
3534 byte_order);
3535
3536 TRACE_WRITE_V_BLOCK (writer, vnum, val);
3537 }
3538 break;
3539 default:
3540 error (_("Unknown block type '%c' (0x%x) in"
3541 " trace frame"),
3542 block_type, block_type);
3543 }
3544
3545 block += gotten;
3546 offset += gotten;
3547 }
3548 }
3549 else
3550 offset += gotten;
3551
3552 writer->ops->frame_ops->end (writer);
409873ef 3553 }
00bf0b85
SS
3554 }
3555
3f43bc09
YQ
3556 writer->ops->end (writer);
3557}
00bf0b85 3558
3f43bc09 3559/* Return a trace writer for TFILE format. */
00bf0b85 3560
3f43bc09
YQ
3561static struct trace_file_writer *
3562tfile_trace_file_writer_new (void)
3563{
3564 struct tfile_trace_file_writer *writer
3565 = xmalloc (sizeof (struct tfile_trace_file_writer));
00bf0b85 3566
3f43bc09
YQ
3567 writer->base.ops = &tfile_write_ops;
3568 writer->fp = NULL;
3569 writer->pathname = NULL;
00bf0b85 3570
3f43bc09 3571 return (struct trace_file_writer *) writer;
011aacb0
VP
3572}
3573
3574static void
3575trace_save_command (char *args, int from_tty)
3576{
3577 int target_does_save = 0;
3578 char **argv;
3579 char *filename = NULL;
3580 struct cleanup *back_to;
d0353e76 3581 int generate_ctf = 0;
3f43bc09 3582 struct trace_file_writer *writer = NULL;
011aacb0
VP
3583
3584 if (args == NULL)
3585 error_no_arg (_("file in which to save trace data"));
3586
3587 argv = gdb_buildargv (args);
3588 back_to = make_cleanup_freeargv (argv);
3589
3590 for (; *argv; ++argv)
3591 {
3592 if (strcmp (*argv, "-r") == 0)
3593 target_does_save = 1;
d0353e76
YQ
3594 if (strcmp (*argv, "-ctf") == 0)
3595 generate_ctf = 1;
011aacb0
VP
3596 else if (**argv == '-')
3597 error (_("unknown option `%s'"), *argv);
3598 else
3599 filename = *argv;
3600 }
3601
3602 if (!filename)
3603 error_no_arg (_("file in which to save trace data"));
3604
d0353e76
YQ
3605 if (generate_ctf)
3606 writer = ctf_trace_file_writer_new ();
3607 else
3608 writer = tfile_trace_file_writer_new ();
3f43bc09
YQ
3609
3610 make_cleanup (trace_file_writer_xfree, writer);
3611
3612 trace_save (filename, writer, target_does_save);
011aacb0 3613
00bf0b85 3614 if (from_tty)
d0353e76
YQ
3615 printf_filtered (_("Trace data saved to %s '%s'.\n"),
3616 generate_ctf ? "directory" : "file", filename);
011aacb0
VP
3617
3618 do_cleanups (back_to);
00bf0b85
SS
3619}
3620
3f43bc09
YQ
3621/* Save the trace data to file FILENAME of tfile format. */
3622
3623void
3624trace_save_tfile (const char *filename, int target_does_save)
3625{
3626 struct trace_file_writer *writer;
3627 struct cleanup *back_to;
3628
3629 writer = tfile_trace_file_writer_new ();
3630 back_to = make_cleanup (trace_file_writer_xfree, writer);
3631 trace_save (filename, writer, target_does_save);
3632 do_cleanups (back_to);
3633}
3634
d0353e76
YQ
3635/* Save the trace data to dir DIRNAME of ctf format. */
3636
3637void
3638trace_save_ctf (const char *dirname, int target_does_save)
3639{
3640 struct trace_file_writer *writer;
3641 struct cleanup *back_to;
3642
3643 writer = ctf_trace_file_writer_new ();
3644 back_to = make_cleanup (trace_file_writer_xfree, writer);
3645
3646 trace_save (dirname, writer, target_does_save);
3647 do_cleanups (back_to);
3648}
3649
d5551862
SS
3650/* Tell the target what to do with an ongoing tracing run if GDB
3651 disconnects for some reason. */
3652
d5551862
SS
3653static void
3654set_disconnected_tracing (char *args, int from_tty,
3655 struct cmd_list_element *c)
3656{
f196051f 3657 target_set_disconnected_tracing (disconnected_tracing);
d5551862
SS
3658}
3659
4daf5ac0
SS
3660static void
3661set_circular_trace_buffer (char *args, int from_tty,
3662 struct cmd_list_element *c)
3663{
3664 target_set_circular_trace_buffer (circular_trace_buffer);
3665}
3666
f6f899bf
HAQ
3667static void
3668set_trace_buffer_size (char *args, int from_tty,
3669 struct cmd_list_element *c)
3670{
3671 target_set_trace_buffer_size (trace_buffer_size);
3672}
3673
f196051f
SS
3674static void
3675set_trace_user (char *args, int from_tty,
3676 struct cmd_list_element *c)
3677{
3678 int ret;
3679
3680 ret = target_set_trace_notes (trace_user, NULL, NULL);
3681
3682 if (!ret)
43011e52 3683 warning (_("Target does not support trace notes, user ignored"));
f196051f
SS
3684}
3685
3686static void
3687set_trace_notes (char *args, int from_tty,
3688 struct cmd_list_element *c)
3689{
3690 int ret;
3691
3692 ret = target_set_trace_notes (NULL, trace_notes, NULL);
3693
3694 if (!ret)
43011e52 3695 warning (_("Target does not support trace notes, note ignored"));
f196051f
SS
3696}
3697
3698static void
3699set_trace_stop_notes (char *args, int from_tty,
3700 struct cmd_list_element *c)
3701{
3702 int ret;
3703
3704 ret = target_set_trace_notes (NULL, NULL, trace_stop_notes);
3705
3706 if (!ret)
43011e52 3707 warning (_("Target does not support trace notes, stop note ignored"));
f196051f
SS
3708}
3709
c906108c
SS
3710/* Convert the memory pointed to by mem into hex, placing result in buf.
3711 * Return a pointer to the last char put in buf (null)
3712 * "stolen" from sparc-stub.c
3713 */
3714
c5aa993b 3715static const char hexchars[] = "0123456789abcdef";
c906108c 3716
47b667de
AC
3717static char *
3718mem2hex (gdb_byte *mem, char *buf, int count)
c906108c 3719{
47b667de 3720 gdb_byte ch;
c906108c
SS
3721
3722 while (count-- > 0)
3723 {
3724 ch = *mem++;
3725
3726 *buf++ = hexchars[ch >> 4];
3727 *buf++ = hexchars[ch & 0xf];
3728 }
3729
3730 *buf = 0;
3731
3732 return buf;
3733}
3734
c5aa993b 3735int
fba45db2 3736get_traceframe_number (void)
c906108c 3737{
c5aa993b 3738 return traceframe_number;
c906108c
SS
3739}
3740
393fd4c3
YQ
3741int
3742get_tracepoint_number (void)
3743{
3744 return tracepoint_number;
3745}
3746
06cd862c
PA
3747/* Make the traceframe NUM be the current trace frame. Does nothing
3748 if NUM is already current. */
3749
3750void
e6e4e701 3751set_current_traceframe (int num)
06cd862c
PA
3752{
3753 int newnum;
3754
3755 if (traceframe_number == num)
3756 {
3757 /* Nothing to do. */
3758 return;
3759 }
3760
3761 newnum = target_trace_find (tfind_number, num, 0, 0, NULL);
3762
3763 if (newnum != num)
3764 warning (_("could not change traceframe"));
3765
8d735b87 3766 set_traceframe_num (newnum);
06cd862c
PA
3767
3768 /* Changing the traceframe changes our view of registers and of the
3769 frame chain. */
3770 registers_changed ();
b3b9301e
PA
3771
3772 clear_traceframe_info ();
06cd862c
PA
3773}
3774
e6e4e701
PA
3775/* Make the traceframe NUM be the current trace frame, and do nothing
3776 more. */
3777
3778void
3779set_traceframe_number (int num)
3780{
3781 traceframe_number = num;
3782}
3783
06cd862c
PA
3784/* A cleanup used when switching away and back from tfind mode. */
3785
3786struct current_traceframe_cleanup
3787{
3788 /* The traceframe we were inspecting. */
3789 int traceframe_number;
3790};
3791
3792static void
3793do_restore_current_traceframe_cleanup (void *arg)
3794{
3795 struct current_traceframe_cleanup *old = arg;
3796
e6e4e701 3797 set_current_traceframe (old->traceframe_number);
06cd862c
PA
3798}
3799
3800static void
3801restore_current_traceframe_cleanup_dtor (void *arg)
3802{
3803 struct current_traceframe_cleanup *old = arg;
3804
3805 xfree (old);
3806}
3807
3808struct cleanup *
3809make_cleanup_restore_current_traceframe (void)
3810{
3811 struct current_traceframe_cleanup *old;
3812
3813 old = xmalloc (sizeof (struct current_traceframe_cleanup));
3814 old->traceframe_number = traceframe_number;
3815
3816 return make_cleanup_dtor (do_restore_current_traceframe_cleanup, old,
3817 restore_current_traceframe_cleanup_dtor);
3818}
00bf0b85 3819
e6e4e701
PA
3820struct cleanup *
3821make_cleanup_restore_traceframe_number (void)
3822{
3823 return make_cleanup_restore_integer (&traceframe_number);
3824}
3825
00bf0b85
SS
3826/* Given a number and address, return an uploaded tracepoint with that
3827 number, creating if necessary. */
3828
3829struct uploaded_tp *
3830get_uploaded_tp (int num, ULONGEST addr, struct uploaded_tp **utpp)
3831{
3832 struct uploaded_tp *utp;
3833
3834 for (utp = *utpp; utp; utp = utp->next)
3835 if (utp->number == num && utp->addr == addr)
3836 return utp;
3837 utp = (struct uploaded_tp *) xmalloc (sizeof (struct uploaded_tp));
3838 memset (utp, 0, sizeof (struct uploaded_tp));
3839 utp->number = num;
3840 utp->addr = addr;
3149d8c1
SS
3841 utp->actions = NULL;
3842 utp->step_actions = NULL;
3843 utp->cmd_strings = NULL;
00bf0b85
SS
3844 utp->next = *utpp;
3845 *utpp = utp;
3846 return utp;
3847}
3848
3849static void
3850free_uploaded_tps (struct uploaded_tp **utpp)
3851{
3852 struct uploaded_tp *next_one;
3853
3854 while (*utpp)
3855 {
3856 next_one = (*utpp)->next;
3857 xfree (*utpp);
3858 *utpp = next_one;
3859 }
3860}
3861
3862/* Given a number and address, return an uploaded tracepoint with that
3863 number, creating if necessary. */
3864
393fd4c3 3865struct uploaded_tsv *
00bf0b85
SS
3866get_uploaded_tsv (int num, struct uploaded_tsv **utsvp)
3867{
3868 struct uploaded_tsv *utsv;
3869
3870 for (utsv = *utsvp; utsv; utsv = utsv->next)
3871 if (utsv->number == num)
3872 return utsv;
3873 utsv = (struct uploaded_tsv *) xmalloc (sizeof (struct uploaded_tsv));
3874 memset (utsv, 0, sizeof (struct uploaded_tsv));
3875 utsv->number = num;
3876 utsv->next = *utsvp;
3877 *utsvp = utsv;
3878 return utsv;
3879}
3880
3881static void
3882free_uploaded_tsvs (struct uploaded_tsv **utsvp)
3883{
3884 struct uploaded_tsv *next_one;
3885
3886 while (*utsvp)
3887 {
3888 next_one = (*utsvp)->next;
3889 xfree (*utsvp);
3890 *utsvp = next_one;
3891 }
3892}
3893
4e5c165d
HZ
3894/* FIXME this function is heuristic and will miss the cases where the
3895 conditional is semantically identical but differs in whitespace,
3896 such as "x == 0" vs "x==0". */
3897
3898static int
3899cond_string_is_same (char *str1, char *str2)
3900{
3901 if (str1 == NULL || str2 == NULL)
3902 return (str1 == str2);
3903
3904 return (strcmp (str1, str2) == 0);
3905}
3906
00bf0b85
SS
3907/* Look for an existing tracepoint that seems similar enough to the
3908 uploaded one. Enablement isn't compared, because the user can
3909 toggle that freely, and may have done so in anticipation of the
1e4d1764 3910 next trace run. Return the location of matched tracepoint. */
00bf0b85 3911
70221824 3912static struct bp_location *
1e4d1764 3913find_matching_tracepoint_location (struct uploaded_tp *utp)
00bf0b85
SS
3914{
3915 VEC(breakpoint_p) *tp_vec = all_tracepoints ();
3916 int ix;
d9b3f62e 3917 struct breakpoint *b;
00bf0b85
SS
3918 struct bp_location *loc;
3919
d9b3f62e 3920 for (ix = 0; VEC_iterate (breakpoint_p, tp_vec, ix, b); ix++)
00bf0b85 3921 {
d9b3f62e
PA
3922 struct tracepoint *t = (struct tracepoint *) b;
3923
3924 if (b->type == utp->type
00bf0b85
SS
3925 && t->step_count == utp->step
3926 && t->pass_count == utp->pass
4e5c165d
HZ
3927 && cond_string_is_same (t->base.cond_string, utp->cond_string)
3928 /* FIXME also test actions. */
00bf0b85
SS
3929 )
3930 {
3931 /* Scan the locations for an address match. */
d9b3f62e 3932 for (loc = b->loc; loc; loc = loc->next)
00bf0b85
SS
3933 {
3934 if (loc->address == utp->addr)
1e4d1764 3935 return loc;
00bf0b85
SS
3936 }
3937 }
3938 }
3939 return NULL;
3940}
3941
3942/* Given a list of tracepoints uploaded from a target, attempt to
3943 match them up with existing tracepoints, and create new ones if not
3944 found. */
3945
3946void
3947merge_uploaded_tracepoints (struct uploaded_tp **uploaded_tps)
3948{
3949 struct uploaded_tp *utp;
f2a8bc8a
YQ
3950 /* A set of tracepoints which are modified. */
3951 VEC(breakpoint_p) *modified_tp = NULL;
3952 int ix;
3953 struct breakpoint *b;
00bf0b85
SS
3954
3955 /* Look for GDB tracepoints that match up with our uploaded versions. */
3956 for (utp = *uploaded_tps; utp; utp = utp->next)
3957 {
1e4d1764
YQ
3958 struct bp_location *loc;
3959 struct tracepoint *t;
3960
3961 loc = find_matching_tracepoint_location (utp);
3962 if (loc)
3963 {
f2a8bc8a
YQ
3964 int found = 0;
3965
1e4d1764
YQ
3966 /* Mark this location as already inserted. */
3967 loc->inserted = 1;
3968 t = (struct tracepoint *) loc->owner;
3969 printf_filtered (_("Assuming tracepoint %d is same "
3970 "as target's tracepoint %d at %s.\n"),
3971 loc->owner->number, utp->number,
3972 paddress (loc->gdbarch, utp->addr));
f2a8bc8a
YQ
3973
3974 /* The tracepoint LOC->owner was modified (the location LOC
3975 was marked as inserted in the target). Save it in
3976 MODIFIED_TP if not there yet. The 'breakpoint-modified'
3977 observers will be notified later once for each tracepoint
3978 saved in MODIFIED_TP. */
3979 for (ix = 0;
3980 VEC_iterate (breakpoint_p, modified_tp, ix, b);
3981 ix++)
3982 if (b == loc->owner)
3983 {
3984 found = 1;
3985 break;
3986 }
3987 if (!found)
3988 VEC_safe_push (breakpoint_p, modified_tp, loc->owner);
1e4d1764 3989 }
00bf0b85
SS
3990 else
3991 {
3992 t = create_tracepoint_from_upload (utp);
3993 if (t)
3e43a32a
MS
3994 printf_filtered (_("Created tracepoint %d for "
3995 "target's tracepoint %d at %s.\n"),
d9b3f62e 3996 t->base.number, utp->number,
3e43a32a 3997 paddress (get_current_arch (), utp->addr));
00bf0b85 3998 else
3e43a32a
MS
3999 printf_filtered (_("Failed to create tracepoint for target's "
4000 "tracepoint %d at %s, skipping it.\n"),
4001 utp->number,
4002 paddress (get_current_arch (), utp->addr));
00bf0b85
SS
4003 }
4004 /* Whether found or created, record the number used by the
4005 target, to help with mapping target tracepoints back to their
4006 counterparts here. */
4007 if (t)
4008 t->number_on_target = utp->number;
4009 }
4010
f2a8bc8a
YQ
4011 /* Notify 'breakpoint-modified' observer that at least one of B's
4012 locations was changed. */
4013 for (ix = 0; VEC_iterate (breakpoint_p, modified_tp, ix, b); ix++)
4014 observer_notify_breakpoint_modified (b);
4015
4016 VEC_free (breakpoint_p, modified_tp);
00bf0b85
SS
4017 free_uploaded_tps (uploaded_tps);
4018}
4019
4020/* Trace state variables don't have much to identify them beyond their
4021 name, so just use that to detect matches. */
4022
70221824 4023static struct trace_state_variable *
00bf0b85
SS
4024find_matching_tsv (struct uploaded_tsv *utsv)
4025{
4026 if (!utsv->name)
4027 return NULL;
4028
4029 return find_trace_state_variable (utsv->name);
4030}
4031
70221824 4032static struct trace_state_variable *
00bf0b85
SS
4033create_tsv_from_upload (struct uploaded_tsv *utsv)
4034{
4035 const char *namebase;
df5a4bd3 4036 char *buf;
00bf0b85
SS
4037 int try_num = 0;
4038 struct trace_state_variable *tsv;
df5a4bd3 4039 struct cleanup *old_chain;
00bf0b85
SS
4040
4041 if (utsv->name)
4042 {
4043 namebase = utsv->name;
df5a4bd3 4044 buf = xstrprintf ("%s", namebase);
00bf0b85
SS
4045 }
4046 else
4047 {
4048 namebase = "__tsv";
df5a4bd3 4049 buf = xstrprintf ("%s_%d", namebase, try_num++);
00bf0b85
SS
4050 }
4051
4052 /* Fish for a name that is not in use. */
c378eb4e 4053 /* (should check against all internal vars?) */
00bf0b85 4054 while (find_trace_state_variable (buf))
df5a4bd3
HZ
4055 {
4056 xfree (buf);
4057 buf = xstrprintf ("%s_%d", namebase, try_num++);
4058 }
4059
4060 old_chain = make_cleanup (xfree, buf);
00bf0b85
SS
4061
4062 /* We have an available name, create the variable. */
a0aa2878 4063 tsv = create_trace_state_variable (buf);
00bf0b85
SS
4064 tsv->initial_value = utsv->initial_value;
4065 tsv->builtin = utsv->builtin;
4066
134a2066 4067 observer_notify_tsv_created (tsv);
bb25a15c 4068
df5a4bd3
HZ
4069 do_cleanups (old_chain);
4070
00bf0b85
SS
4071 return tsv;
4072}
4073
4074/* Given a list of uploaded trace state variables, try to match them
4075 up with existing variables, or create additional ones. */
4076
4077void
4078merge_uploaded_trace_state_variables (struct uploaded_tsv **uploaded_tsvs)
4079{
4080 int ix;
4081 struct uploaded_tsv *utsv;
4082 struct trace_state_variable *tsv;
4083 int highest;
4084
4085 /* Most likely some numbers will have to be reassigned as part of
4086 the merge, so clear them all in anticipation. */
4087 for (ix = 0; VEC_iterate (tsv_s, tvariables, ix, tsv); ++ix)
4088 tsv->number = 0;
4089
4090 for (utsv = *uploaded_tsvs; utsv; utsv = utsv->next)
4091 {
4092 tsv = find_matching_tsv (utsv);
4093 if (tsv)
417b5110
DJ
4094 {
4095 if (info_verbose)
3e43a32a
MS
4096 printf_filtered (_("Assuming trace state variable $%s "
4097 "is same as target's variable %d.\n"),
417b5110
DJ
4098 tsv->name, utsv->number);
4099 }
00bf0b85
SS
4100 else
4101 {
4102 tsv = create_tsv_from_upload (utsv);
417b5110 4103 if (info_verbose)
3e43a32a
MS
4104 printf_filtered (_("Created trace state variable "
4105 "$%s for target's variable %d.\n"),
417b5110 4106 tsv->name, utsv->number);
00bf0b85
SS
4107 }
4108 /* Give precedence to numberings that come from the target. */
4109 if (tsv)
4110 tsv->number = utsv->number;
4111 }
4112
4113 /* Renumber everything that didn't get a target-assigned number. */
4114 highest = 0;
4115 for (ix = 0; VEC_iterate (tsv_s, tvariables, ix, tsv); ++ix)
4116 if (tsv->number > highest)
4117 highest = tsv->number;
4118
4119 ++highest;
4120 for (ix = 0; VEC_iterate (tsv_s, tvariables, ix, tsv); ++ix)
4121 if (tsv->number == 0)
4122 tsv->number = highest++;
4123
4124 free_uploaded_tsvs (uploaded_tsvs);
4125}
4126
4127/* target tfile command */
4128
1467929f 4129static struct target_ops tfile_ops;
00bf0b85
SS
4130
4131/* Fill in tfile_ops with its defined operations and properties. */
4132
4133#define TRACE_HEADER_SIZE 8
4134
1467929f
YQ
4135static char *trace_filename;
4136static int trace_fd = -1;
4137static off_t trace_frames_offset;
4138static off_t cur_offset;
4139static int cur_data_size;
00bf0b85
SS
4140int trace_regblock_size;
4141
4142static void tfile_interp_line (char *line,
4143 struct uploaded_tp **utpp,
4144 struct uploaded_tsv **utsvp);
4145
9f41c731
PA
4146/* Read SIZE bytes into READBUF from the trace frame, starting at
4147 TRACE_FD's current position. Note that this call `read'
4148 underneath, hence it advances the file's seek position. Throws an
4149 error if the `read' syscall fails, or less than SIZE bytes are
4150 read. */
4151
4152static void
4153tfile_read (gdb_byte *readbuf, int size)
4154{
4155 int gotten;
4156
4157 gotten = read (trace_fd, readbuf, size);
4158 if (gotten < 0)
4159 perror_with_name (trace_filename);
4160 else if (gotten < size)
4161 error (_("Premature end of file while reading trace file"));
4162}
4163
00bf0b85
SS
4164static void
4165tfile_open (char *filename, int from_tty)
4166{
e93a69ed 4167 volatile struct gdb_exception ex;
00bf0b85
SS
4168 char *temp;
4169 struct cleanup *old_chain;
4170 int flags;
4171 int scratch_chan;
4172 char header[TRACE_HEADER_SIZE];
c378eb4e 4173 char linebuf[1000]; /* Should be max remote packet size or so. */
bc20a4af 4174 gdb_byte byte;
9f41c731 4175 int bytes, i;
00bf0b85
SS
4176 struct trace_status *ts;
4177 struct uploaded_tp *uploaded_tps = NULL;
4178 struct uploaded_tsv *uploaded_tsvs = NULL;
4179
4180 target_preopen (from_tty);
4181 if (!filename)
4182 error (_("No trace file specified."));
4183
4184 filename = tilde_expand (filename);
4185 if (!IS_ABSOLUTE_PATH(filename))
4186 {
c4f7c687 4187 temp = concat (current_directory, "/", filename, (char *) NULL);
00bf0b85
SS
4188 xfree (filename);
4189 filename = temp;
4190 }
4191
4192 old_chain = make_cleanup (xfree, filename);
4193
4194 flags = O_BINARY | O_LARGEFILE;
4195 flags |= O_RDONLY;
614c279d 4196 scratch_chan = gdb_open_cloexec (filename, flags, 0);
00bf0b85
SS
4197 if (scratch_chan < 0)
4198 perror_with_name (filename);
4199
4200 /* Looks semi-reasonable. Toss the old trace file and work on the new. */
4201
c378eb4e 4202 discard_cleanups (old_chain); /* Don't free filename any more. */
00bf0b85
SS
4203 unpush_target (&tfile_ops);
4204
98e03262 4205 trace_filename = xstrdup (filename);
00bf0b85
SS
4206 trace_fd = scratch_chan;
4207
4208 bytes = 0;
4209 /* Read the file header and test for validity. */
9f41c731 4210 tfile_read ((gdb_byte *) &header, TRACE_HEADER_SIZE);
98e03262 4211
00bf0b85
SS
4212 bytes += TRACE_HEADER_SIZE;
4213 if (!(header[0] == 0x7f
4214 && (strncmp (header + 1, "TRACE0\n", 7) == 0)))
4215 error (_("File is not a valid trace file."));
4216
e93a69ed
PA
4217 push_target (&tfile_ops);
4218
00bf0b85
SS
4219 trace_regblock_size = 0;
4220 ts = current_trace_status ();
f5911ea1
HAQ
4221 /* We know we're working with a file. Record its name. */
4222 ts->filename = trace_filename;
00bf0b85
SS
4223 /* Set defaults in case there is no status line. */
4224 ts->running_known = 0;
4225 ts->stop_reason = trace_stop_reason_unknown;
4226 ts->traceframe_count = -1;
4227 ts->buffer_free = 0;
33da3f1c
SS
4228 ts->disconnected_tracing = 0;
4229 ts->circular_buffer = 0;
00bf0b85 4230
e93a69ed 4231 TRY_CATCH (ex, RETURN_MASK_ALL)
00bf0b85 4232 {
e93a69ed
PA
4233 /* Read through a section of newline-terminated lines that
4234 define things like tracepoints. */
4235 i = 0;
4236 while (1)
00bf0b85 4237 {
e93a69ed
PA
4238 tfile_read (&byte, 1);
4239
4240 ++bytes;
4241 if (byte == '\n')
4242 {
4243 /* Empty line marks end of the definition section. */
4244 if (i == 0)
4245 break;
4246 linebuf[i] = '\0';
4247 i = 0;
4248 tfile_interp_line (linebuf, &uploaded_tps, &uploaded_tsvs);
4249 }
4250 else
4251 linebuf[i++] = byte;
4252 if (i >= 1000)
4253 error (_("Excessively long lines in trace file"));
00bf0b85 4254 }
e93a69ed
PA
4255
4256 /* Record the starting offset of the binary trace data. */
4257 trace_frames_offset = bytes;
4258
4259 /* If we don't have a blocksize, we can't interpret the
4260 traceframes. */
4261 if (trace_regblock_size == 0)
4262 error (_("No register block size recorded in trace file"));
4263 }
4264 if (ex.reason < 0)
4265 {
4266 /* Pop the partially set up target. */
4267 pop_target ();
4268 throw_exception (ex);
00bf0b85
SS
4269 }
4270
e93a69ed
PA
4271 if (ts->traceframe_count <= 0)
4272 warning (_("No traceframes present in this file."));
4273
00bf0b85
SS
4274 /* Add the file's tracepoints and variables into the current mix. */
4275
10ef8d6a
PA
4276 /* Get trace state variables first, they may be checked when parsing
4277 uploaded commands. */
00bf0b85
SS
4278 merge_uploaded_trace_state_variables (&uploaded_tsvs);
4279
10ef8d6a 4280 merge_uploaded_tracepoints (&uploaded_tps);
00bf0b85
SS
4281}
4282
4283/* Interpret the given line from the definitions part of the trace
4284 file. */
4285
4286static void
cf2cb5ec
YQ
4287tfile_interp_line (char *line, struct uploaded_tp **utpp,
4288 struct uploaded_tsv **utsvp)
00bf0b85
SS
4289{
4290 char *p = line;
4291
4292 if (strncmp (p, "R ", strlen ("R ")) == 0)
4293 {
4294 p += strlen ("R ");
4295 trace_regblock_size = strtol (p, &p, 16);
4296 }
4297 else if (strncmp (p, "status ", strlen ("status ")) == 0)
4298 {
4299 p += strlen ("status ");
4300 parse_trace_status (p, current_trace_status ());
4301 }
4302 else if (strncmp (p, "tp ", strlen ("tp ")) == 0)
4303 {
4304 p += strlen ("tp ");
4305 parse_tracepoint_definition (p, utpp);
4306 }
4307 else if (strncmp (p, "tsv ", strlen ("tsv ")) == 0)
4308 {
4309 p += strlen ("tsv ");
4310 parse_tsv_definition (p, utsvp);
4311 }
4312 else
a73c6dcd 4313 warning (_("Ignoring trace file definition \"%s\""), line);
00bf0b85
SS
4314}
4315
4316/* Parse the part of trace status syntax that is shared between
4317 the remote protocol and the trace file reader. */
4318
00bf0b85
SS
4319void
4320parse_trace_status (char *line, struct trace_status *ts)
4321{
f196051f
SS
4322 char *p = line, *p1, *p2, *p3, *p_temp;
4323 int end;
00bf0b85
SS
4324 ULONGEST val;
4325
4326 ts->running_known = 1;
4327 ts->running = (*p++ == '1');
4328 ts->stop_reason = trace_stop_reason_unknown;
f196051f
SS
4329 xfree (ts->stop_desc);
4330 ts->stop_desc = NULL;
4daf5ac0
SS
4331 ts->traceframe_count = -1;
4332 ts->traceframes_created = -1;
4333 ts->buffer_free = -1;
4334 ts->buffer_size = -1;
33da3f1c
SS
4335 ts->disconnected_tracing = 0;
4336 ts->circular_buffer = 0;
f196051f
SS
4337 xfree (ts->user_name);
4338 ts->user_name = NULL;
4339 xfree (ts->notes);
4340 ts->notes = NULL;
4341 ts->start_time = ts->stop_time = 0;
4daf5ac0 4342
00bf0b85
SS
4343 while (*p++)
4344 {
4345 p1 = strchr (p, ':');
4346 if (p1 == NULL)
4347 error (_("Malformed trace status, at %s\n\
4348Status line: '%s'\n"), p, line);
f196051f
SS
4349 p3 = strchr (p, ';');
4350 if (p3 == NULL)
4351 p3 = p + strlen (p);
00bf0b85
SS
4352 if (strncmp (p, stop_reason_names[trace_buffer_full], p1 - p) == 0)
4353 {
4354 p = unpack_varlen_hex (++p1, &val);
4355 ts->stop_reason = trace_buffer_full;
4356 }
4357 else if (strncmp (p, stop_reason_names[trace_never_run], p1 - p) == 0)
4358 {
4359 p = unpack_varlen_hex (++p1, &val);
4360 ts->stop_reason = trace_never_run;
4361 }
3e43a32a
MS
4362 else if (strncmp (p, stop_reason_names[tracepoint_passcount],
4363 p1 - p) == 0)
00bf0b85
SS
4364 {
4365 p = unpack_varlen_hex (++p1, &val);
4366 ts->stop_reason = tracepoint_passcount;
4367 ts->stopping_tracepoint = val;
4368 }
4369 else if (strncmp (p, stop_reason_names[tstop_command], p1 - p) == 0)
4370 {
f196051f
SS
4371 p2 = strchr (++p1, ':');
4372 if (!p2 || p2 > p3)
4373 {
4374 /*older style*/
4375 p2 = p1;
4376 }
4377 else if (p2 != p1)
4378 {
4379 ts->stop_desc = xmalloc (strlen (line));
bc20a4af 4380 end = hex2bin (p1, (gdb_byte *) ts->stop_desc, (p2 - p1) / 2);
f196051f
SS
4381 ts->stop_desc[end] = '\0';
4382 }
4383 else
4384 ts->stop_desc = xstrdup ("");
4385
4386 p = unpack_varlen_hex (++p2, &val);
00bf0b85
SS
4387 ts->stop_reason = tstop_command;
4388 }
33da3f1c
SS
4389 else if (strncmp (p, stop_reason_names[trace_disconnected], p1 - p) == 0)
4390 {
4391 p = unpack_varlen_hex (++p1, &val);
4392 ts->stop_reason = trace_disconnected;
4393 }
6c28cbf2
SS
4394 else if (strncmp (p, stop_reason_names[tracepoint_error], p1 - p) == 0)
4395 {
4396 p2 = strchr (++p1, ':');
4397 if (p2 != p1)
4398 {
f196051f 4399 ts->stop_desc = xmalloc ((p2 - p1) / 2 + 1);
bc20a4af 4400 end = hex2bin (p1, (gdb_byte *) ts->stop_desc, (p2 - p1) / 2);
f196051f 4401 ts->stop_desc[end] = '\0';
6c28cbf2 4402 }
a609a0c8 4403 else
f196051f 4404 ts->stop_desc = xstrdup ("");
a609a0c8 4405
6c28cbf2
SS
4406 p = unpack_varlen_hex (++p2, &val);
4407 ts->stopping_tracepoint = val;
4408 ts->stop_reason = tracepoint_error;
4409 }
4daf5ac0 4410 else if (strncmp (p, "tframes", p1 - p) == 0)
00bf0b85
SS
4411 {
4412 p = unpack_varlen_hex (++p1, &val);
4413 ts->traceframe_count = val;
4414 }
4daf5ac0
SS
4415 else if (strncmp (p, "tcreated", p1 - p) == 0)
4416 {
4417 p = unpack_varlen_hex (++p1, &val);
4418 ts->traceframes_created = val;
4419 }
4420 else if (strncmp (p, "tfree", p1 - p) == 0)
00bf0b85
SS
4421 {
4422 p = unpack_varlen_hex (++p1, &val);
4423 ts->buffer_free = val;
4424 }
4daf5ac0
SS
4425 else if (strncmp (p, "tsize", p1 - p) == 0)
4426 {
4427 p = unpack_varlen_hex (++p1, &val);
4428 ts->buffer_size = val;
4429 }
33da3f1c
SS
4430 else if (strncmp (p, "disconn", p1 - p) == 0)
4431 {
4432 p = unpack_varlen_hex (++p1, &val);
4433 ts->disconnected_tracing = val;
4434 }
4435 else if (strncmp (p, "circular", p1 - p) == 0)
4436 {
4437 p = unpack_varlen_hex (++p1, &val);
4438 ts->circular_buffer = val;
4439 }
f196051f
SS
4440 else if (strncmp (p, "starttime", p1 - p) == 0)
4441 {
4442 p = unpack_varlen_hex (++p1, &val);
4443 ts->start_time = val;
4444 }
4445 else if (strncmp (p, "stoptime", p1 - p) == 0)
4446 {
4447 p = unpack_varlen_hex (++p1, &val);
4448 ts->stop_time = val;
4449 }
4450 else if (strncmp (p, "username", p1 - p) == 0)
4451 {
4452 ++p1;
4453 ts->user_name = xmalloc (strlen (p) / 2);
bc20a4af 4454 end = hex2bin (p1, (gdb_byte *) ts->user_name, (p3 - p1) / 2);
f196051f
SS
4455 ts->user_name[end] = '\0';
4456 p = p3;
4457 }
4458 else if (strncmp (p, "notes", p1 - p) == 0)
4459 {
4460 ++p1;
4461 ts->notes = xmalloc (strlen (p) / 2);
bc20a4af 4462 end = hex2bin (p1, (gdb_byte *) ts->notes, (p3 - p1) / 2);
f196051f
SS
4463 ts->notes[end] = '\0';
4464 p = p3;
4465 }
00bf0b85
SS
4466 else
4467 {
4468 /* Silently skip unknown optional info. */
4469 p_temp = strchr (p1 + 1, ';');
4470 if (p_temp)
4471 p = p_temp;
4472 else
4473 /* Must be at the end. */
4474 break;
4475 }
4476 }
4477}
4478
f196051f
SS
4479void
4480parse_tracepoint_status (char *p, struct breakpoint *bp,
4481 struct uploaded_tp *utp)
4482{
4483 ULONGEST uval;
4484 struct tracepoint *tp = (struct tracepoint *) bp;
4485
4486 p = unpack_varlen_hex (p, &uval);
4487 if (tp)
4488 tp->base.hit_count += uval;
4489 else
4490 utp->hit_count += uval;
4491 p = unpack_varlen_hex (p + 1, &uval);
4492 if (tp)
4493 tp->traceframe_usage += uval;
4494 else
4495 utp->traceframe_usage += uval;
4496 /* Ignore any extra, allowing for future extensions. */
4497}
4498
409873ef
SS
4499/* Given a line of text defining a part of a tracepoint, parse it into
4500 an "uploaded tracepoint". */
00bf0b85
SS
4501
4502void
4503parse_tracepoint_definition (char *line, struct uploaded_tp **utpp)
4504{
4505 char *p;
4506 char piece;
409873ef 4507 ULONGEST num, addr, step, pass, orig_size, xlen, start;
2a2287c7 4508 int enabled, end;
00bf0b85 4509 enum bptype type;
2a2287c7 4510 char *cond, *srctype, *buf;
00bf0b85
SS
4511 struct uploaded_tp *utp = NULL;
4512
4513 p = line;
4514 /* Both tracepoint and action definitions start with the same number
4515 and address sequence. */
4516 piece = *p++;
4517 p = unpack_varlen_hex (p, &num);
4518 p++; /* skip a colon */
4519 p = unpack_varlen_hex (p, &addr);
4520 p++; /* skip a colon */
4521 if (piece == 'T')
4522 {
4523 enabled = (*p++ == 'E');
4524 p++; /* skip a colon */
4525 p = unpack_varlen_hex (p, &step);
4526 p++; /* skip a colon */
4527 p = unpack_varlen_hex (p, &pass);
4528 type = bp_tracepoint;
4529 cond = NULL;
4530 /* Thumb through optional fields. */
4531 while (*p == ':')
4532 {
4533 p++; /* skip a colon */
4534 if (*p == 'F')
4535 {
4536 type = bp_fast_tracepoint;
4537 p++;
4538 p = unpack_varlen_hex (p, &orig_size);
4539 }
0fb4aa4b
PA
4540 else if (*p == 'S')
4541 {
4542 type = bp_static_tracepoint;
4543 p++;
4544 }
00bf0b85
SS
4545 else if (*p == 'X')
4546 {
4547 p++;
4548 p = unpack_varlen_hex (p, &xlen);
4549 p++; /* skip a comma */
4550 cond = (char *) xmalloc (2 * xlen + 1);
4551 strncpy (cond, p, 2 * xlen);
4552 cond[2 * xlen] = '\0';
4553 p += 2 * xlen;
4554 }
4555 else
3e43a32a
MS
4556 warning (_("Unrecognized char '%c' in tracepoint "
4557 "definition, skipping rest"), *p);
00bf0b85
SS
4558 }
4559 utp = get_uploaded_tp (num, addr, utpp);
4560 utp->type = type;
4561 utp->enabled = enabled;
4562 utp->step = step;
4563 utp->pass = pass;
4564 utp->cond = cond;
4565 }
4566 else if (piece == 'A')
4567 {
4568 utp = get_uploaded_tp (num, addr, utpp);
3149d8c1 4569 VEC_safe_push (char_ptr, utp->actions, xstrdup (p));
00bf0b85
SS
4570 }
4571 else if (piece == 'S')
4572 {
4573 utp = get_uploaded_tp (num, addr, utpp);
3149d8c1 4574 VEC_safe_push (char_ptr, utp->step_actions, xstrdup (p));
00bf0b85 4575 }
409873ef
SS
4576 else if (piece == 'Z')
4577 {
4578 /* Parse a chunk of source form definition. */
4579 utp = get_uploaded_tp (num, addr, utpp);
4580 srctype = p;
4581 p = strchr (p, ':');
4582 p++; /* skip a colon */
4583 p = unpack_varlen_hex (p, &start);
4584 p++; /* skip a colon */
4585 p = unpack_varlen_hex (p, &xlen);
4586 p++; /* skip a colon */
4587
4588 buf = alloca (strlen (line));
4589
4590 end = hex2bin (p, (gdb_byte *) buf, strlen (p) / 2);
4591 buf[end] = '\0';
4592
4593 if (strncmp (srctype, "at:", strlen ("at:")) == 0)
4594 utp->at_string = xstrdup (buf);
4595 else if (strncmp (srctype, "cond:", strlen ("cond:")) == 0)
4596 utp->cond_string = xstrdup (buf);
4597 else if (strncmp (srctype, "cmd:", strlen ("cmd:")) == 0)
3149d8c1 4598 VEC_safe_push (char_ptr, utp->cmd_strings, xstrdup (buf));
409873ef 4599 }
f196051f
SS
4600 else if (piece == 'V')
4601 {
4602 utp = get_uploaded_tp (num, addr, utpp);
4603
4604 parse_tracepoint_status (p, NULL, utp);
4605 }
00bf0b85
SS
4606 else
4607 {
409873ef
SS
4608 /* Don't error out, the target might be sending us optional
4609 info that we don't care about. */
4610 warning (_("Unrecognized tracepoint piece '%c', ignoring"), piece);
00bf0b85
SS
4611 }
4612}
4613
4614/* Convert a textual description of a trace state variable into an
4615 uploaded object. */
4616
4617void
4618parse_tsv_definition (char *line, struct uploaded_tsv **utsvp)
4619{
4620 char *p, *buf;
4621 ULONGEST num, initval, builtin;
4622 int end;
4623 struct uploaded_tsv *utsv = NULL;
4624
4625 buf = alloca (strlen (line));
4626
4627 p = line;
4628 p = unpack_varlen_hex (p, &num);
4629 p++; /* skip a colon */
4630 p = unpack_varlen_hex (p, &initval);
4631 p++; /* skip a colon */
4632 p = unpack_varlen_hex (p, &builtin);
4633 p++; /* skip a colon */
4634 end = hex2bin (p, (gdb_byte *) buf, strlen (p) / 2);
4635 buf[end] = '\0';
4636
4637 utsv = get_uploaded_tsv (num, utsvp);
4638 utsv->initial_value = initval;
4639 utsv->builtin = builtin;
4640 utsv->name = xstrdup (buf);
4641}
4642
4643/* Close the trace file and generally clean up. */
4644
4645static void
460014f5 4646tfile_close (void)
00bf0b85
SS
4647{
4648 int pid;
4649
4650 if (trace_fd < 0)
4651 return;
4652
00bf0b85
SS
4653 close (trace_fd);
4654 trace_fd = -1;
e93a69ed
PA
4655 xfree (trace_filename);
4656 trace_filename = NULL;
00bf0b85
SS
4657}
4658
4659static void
4660tfile_files_info (struct target_ops *t)
4661{
f5911ea1 4662 printf_filtered ("\t`%s'\n", trace_filename);
00bf0b85
SS
4663}
4664
4665/* The trace status for a file is that tracing can never be run. */
4666
4667static int
4668tfile_get_trace_status (struct trace_status *ts)
4669{
4670 /* Other bits of trace status were collected as part of opening the
4671 trace files, so nothing to do here. */
4672
4673 return -1;
4674}
4675
f196051f
SS
4676static void
4677tfile_get_tracepoint_status (struct breakpoint *tp, struct uploaded_tp *utp)
4678{
4679 /* Other bits of trace status were collected as part of opening the
4680 trace files, so nothing to do here. */
4681}
4682
00bf0b85
SS
4683/* Given the position of a traceframe in the file, figure out what
4684 address the frame was collected at. This would normally be the
4685 value of a collected PC register, but if not available, we
4686 improvise. */
4687
cc5925ad 4688static CORE_ADDR
00bf0b85
SS
4689tfile_get_traceframe_address (off_t tframe_offset)
4690{
cc5925ad 4691 CORE_ADDR addr = 0;
00bf0b85 4692 short tpnum;
d9b3f62e 4693 struct tracepoint *tp;
00bf0b85
SS
4694 off_t saved_offset = cur_offset;
4695
c378eb4e 4696 /* FIXME dig pc out of collected registers. */
00bf0b85
SS
4697
4698 /* Fall back to using tracepoint address. */
4699 lseek (trace_fd, tframe_offset, SEEK_SET);
9f41c731 4700 tfile_read ((gdb_byte *) &tpnum, 2);
8991e9fa
HZ
4701 tpnum = (short) extract_signed_integer ((gdb_byte *) &tpnum, 2,
4702 gdbarch_byte_order
f5656ead 4703 (target_gdbarch ()));
98e03262 4704
00bf0b85 4705 tp = get_tracepoint_by_number_on_target (tpnum);
c378eb4e 4706 /* FIXME this is a poor heuristic if multiple locations. */
d9b3f62e
PA
4707 if (tp && tp->base.loc)
4708 addr = tp->base.loc->address;
00bf0b85
SS
4709
4710 /* Restore our seek position. */
4711 cur_offset = saved_offset;
4712 lseek (trace_fd, cur_offset, SEEK_SET);
4713 return addr;
4714}
4715
4716/* Given a type of search and some parameters, scan the collection of
4717 traceframes in the file looking for a match. When found, return
4718 both the traceframe and tracepoint number, otherwise -1 for
4719 each. */
4720
4721static int
4722tfile_trace_find (enum trace_find_type type, int num,
cc5925ad 4723 CORE_ADDR addr1, CORE_ADDR addr2, int *tpp)
00bf0b85
SS
4724{
4725 short tpnum;
9f41c731 4726 int tfnum = 0, found = 0;
8991e9fa 4727 unsigned int data_size;
d9b3f62e 4728 struct tracepoint *tp;
00bf0b85 4729 off_t offset, tframe_offset;
cc5925ad 4730 CORE_ADDR tfaddr;
00bf0b85 4731
a8a64aa8 4732 if (num == -1)
fb80a3c5
HZ
4733 {
4734 if (tpp)
4735 *tpp = -1;
4736 return -1;
4737 }
e6e4e701 4738
00bf0b85
SS
4739 lseek (trace_fd, trace_frames_offset, SEEK_SET);
4740 offset = trace_frames_offset;
4741 while (1)
4742 {
4743 tframe_offset = offset;
9f41c731 4744 tfile_read ((gdb_byte *) &tpnum, 2);
8991e9fa
HZ
4745 tpnum = (short) extract_signed_integer ((gdb_byte *) &tpnum, 2,
4746 gdbarch_byte_order
f5656ead 4747 (target_gdbarch ()));
00bf0b85
SS
4748 offset += 2;
4749 if (tpnum == 0)
4750 break;
9f41c731 4751 tfile_read ((gdb_byte *) &data_size, 4);
8991e9fa
HZ
4752 data_size = (unsigned int) extract_unsigned_integer
4753 ((gdb_byte *) &data_size, 4,
f5656ead 4754 gdbarch_byte_order (target_gdbarch ()));
00bf0b85 4755 offset += 4;
6c8e944d
YQ
4756
4757 if (type == tfind_number)
00bf0b85 4758 {
6c8e944d 4759 /* Looking for a specific trace frame. */
00bf0b85
SS
4760 if (tfnum == num)
4761 found = 1;
00bf0b85 4762 }
6c8e944d
YQ
4763 else
4764 {
4765 /* Start from the _next_ trace frame. */
4766 if (tfnum > traceframe_number)
4767 {
4768 switch (type)
4769 {
4770 case tfind_pc:
4771 tfaddr = tfile_get_traceframe_address (tframe_offset);
4772 if (tfaddr == addr1)
4773 found = 1;
4774 break;
4775 case tfind_tp:
4776 tp = get_tracepoint (num);
4777 if (tp && tpnum == tp->number_on_target)
4778 found = 1;
4779 break;
4780 case tfind_range:
4781 tfaddr = tfile_get_traceframe_address (tframe_offset);
4782 if (addr1 <= tfaddr && tfaddr <= addr2)
4783 found = 1;
4784 break;
4785 case tfind_outside:
4786 tfaddr = tfile_get_traceframe_address (tframe_offset);
4787 if (!(addr1 <= tfaddr && tfaddr <= addr2))
4788 found = 1;
4789 break;
4790 default:
4791 internal_error (__FILE__, __LINE__, _("unknown tfind type"));
4792 }
4793 }
4794 }
4795
00bf0b85
SS
4796 if (found)
4797 {
00bf0b85
SS
4798 if (tpp)
4799 *tpp = tpnum;
4800 cur_offset = offset;
4801 cur_data_size = data_size;
a8a64aa8 4802
00bf0b85
SS
4803 return tfnum;
4804 }
4805 /* Skip past the traceframe's data. */
4806 lseek (trace_fd, data_size, SEEK_CUR);
4807 offset += data_size;
4808 /* Update our own count of traceframes. */
4809 ++tfnum;
4810 }
4811 /* Did not find what we were looking for. */
4812 if (tpp)
4813 *tpp = -1;
4814 return -1;
4815}
4816
9f41c731
PA
4817/* Prototype of the callback passed to tframe_walk_blocks. */
4818typedef int (*walk_blocks_callback_func) (char blocktype, void *data);
4819
4820/* Callback for traceframe_walk_blocks, used to find a given block
4821 type in a traceframe. */
4822
4823static int
4824match_blocktype (char blocktype, void *data)
4825{
4826 char *wantedp = data;
4827
4828 if (*wantedp == blocktype)
4829 return 1;
4830
4831 return 0;
4832}
4833
4834/* Walk over all traceframe block starting at POS offset from
4835 CUR_OFFSET, and call CALLBACK for each block found, passing in DATA
4836 unmodified. If CALLBACK returns true, this returns the position in
4837 the traceframe where the block is found, relative to the start of
4838 the traceframe (cur_offset). Returns -1 if no callback call
4839 returned true, indicating that all blocks have been walked. */
4840
4841static int
4842traceframe_walk_blocks (walk_blocks_callback_func callback,
4843 int pos, void *data)
4844{
4845 /* Iterate through a traceframe's blocks, looking for a block of the
4846 requested type. */
4847
4848 lseek (trace_fd, cur_offset + pos, SEEK_SET);
4849 while (pos < cur_data_size)
4850 {
4851 unsigned short mlen;
4852 char block_type;
4853
bc20a4af 4854 tfile_read ((gdb_byte *) &block_type, 1);
9f41c731
PA
4855
4856 ++pos;
4857
4858 if ((*callback) (block_type, data))
4859 return pos;
4860
4861 switch (block_type)
4862 {
4863 case 'R':
4864 lseek (trace_fd, cur_offset + pos + trace_regblock_size, SEEK_SET);
4865 pos += trace_regblock_size;
4866 break;
4867 case 'M':
4868 lseek (trace_fd, cur_offset + pos + 8, SEEK_SET);
4869 tfile_read ((gdb_byte *) &mlen, 2);
4870 mlen = (unsigned short)
4871 extract_unsigned_integer ((gdb_byte *) &mlen, 2,
4872 gdbarch_byte_order
f5656ead 4873 (target_gdbarch ()));
9f41c731
PA
4874 lseek (trace_fd, mlen, SEEK_CUR);
4875 pos += (8 + 2 + mlen);
4876 break;
4877 case 'V':
4878 lseek (trace_fd, cur_offset + pos + 4 + 8, SEEK_SET);
4879 pos += (4 + 8);
4880 break;
4881 default:
c2f0d045 4882 error (_("Unknown block type '%c' (0x%x) in trace frame"),
9f41c731
PA
4883 block_type, block_type);
4884 break;
4885 }
4886 }
4887
4888 return -1;
4889}
4890
4891/* Convenience wrapper around traceframe_walk_blocks. Looks for the
4892 position offset of a block of type TYPE_WANTED in the current trace
4893 frame, starting at POS. Returns -1 if no such block was found. */
4894
4895static int
4896traceframe_find_block_type (char type_wanted, int pos)
4897{
4898 return traceframe_walk_blocks (match_blocktype, pos, &type_wanted);
4899}
4900
00bf0b85
SS
4901/* Look for a block of saved registers in the traceframe, and get the
4902 requested register from it. */
4903
4904static void
4905tfile_fetch_registers (struct target_ops *ops,
4906 struct regcache *regcache, int regno)
4907{
4908 struct gdbarch *gdbarch = get_regcache_arch (regcache);
22e048c9 4909 int offset, regn, regsize, pc_regno;
948f8e3d 4910 gdb_byte *regs;
00bf0b85
SS
4911
4912 /* An uninitialized reg size says we're not going to be
4913 successful at getting register blocks. */
4914 if (!trace_regblock_size)
4915 return;
4916
4917 regs = alloca (trace_regblock_size);
4918
9f41c731 4919 if (traceframe_find_block_type ('R', 0) >= 0)
00bf0b85 4920 {
9f41c731 4921 tfile_read (regs, trace_regblock_size);
98e03262 4922
9f41c731
PA
4923 /* Assume the block is laid out in GDB register number order,
4924 each register with the size that it has in GDB. */
4925 offset = 0;
4926 for (regn = 0; regn < gdbarch_num_regs (gdbarch); regn++)
00bf0b85 4927 {
9f41c731
PA
4928 regsize = register_size (gdbarch, regn);
4929 /* Make sure we stay within block bounds. */
4930 if (offset + regsize >= trace_regblock_size)
4931 break;
4932 if (regcache_register_status (regcache, regn) == REG_UNKNOWN)
00bf0b85 4933 {
9f41c731 4934 if (regno == regn)
00bf0b85 4935 {
9f41c731
PA
4936 regcache_raw_supply (regcache, regno, regs + offset);
4937 break;
4938 }
4939 else if (regno == -1)
4940 {
4941 regcache_raw_supply (regcache, regn, regs + offset);
00bf0b85 4942 }
00bf0b85 4943 }
9f41c731 4944 offset += regsize;
00bf0b85 4945 }
9f41c731 4946 return;
00bf0b85 4947 }
af54718e 4948
9f41c731
PA
4949 /* We get here if no register data has been found. Mark registers
4950 as unavailable. */
af54718e
SS
4951 for (regn = 0; regn < gdbarch_num_regs (gdbarch); regn++)
4952 regcache_raw_supply (regcache, regn, NULL);
4953
4954 /* We can often usefully guess that the PC is going to be the same
4955 as the address of the tracepoint. */
4956 pc_regno = gdbarch_pc_regnum (gdbarch);
4957 if (pc_regno >= 0 && (regno == -1 || regno == pc_regno))
4958 {
d9b3f62e 4959 struct tracepoint *tp = get_tracepoint (tracepoint_number);
af54718e 4960
d9b3f62e 4961 if (tp && tp->base.loc)
af54718e
SS
4962 {
4963 /* But don't try to guess if tracepoint is multi-location... */
d9b3f62e 4964 if (tp->base.loc->next)
af54718e 4965 {
a73c6dcd
MS
4966 warning (_("Tracepoint %d has multiple "
4967 "locations, cannot infer $pc"),
d9b3f62e 4968 tp->base.number);
af54718e
SS
4969 return;
4970 }
4971 /* ... or does while-stepping. */
4972 if (tp->step_count > 0)
4973 {
a73c6dcd
MS
4974 warning (_("Tracepoint %d does while-stepping, "
4975 "cannot infer $pc"),
d9b3f62e 4976 tp->base.number);
af54718e
SS
4977 return;
4978 }
4979
4980 store_unsigned_integer (regs, register_size (gdbarch, pc_regno),
4981 gdbarch_byte_order (gdbarch),
d9b3f62e 4982 tp->base.loc->address);
af54718e
SS
4983 regcache_raw_supply (regcache, pc_regno, regs);
4984 }
4985 }
00bf0b85
SS
4986}
4987
4988static LONGEST
4989tfile_xfer_partial (struct target_ops *ops, enum target_object object,
4990 const char *annex, gdb_byte *readbuf,
4991 const gdb_byte *writebuf, ULONGEST offset, LONGEST len)
4992{
00bf0b85
SS
4993 /* We're only doing regular memory for now. */
4994 if (object != TARGET_OBJECT_MEMORY)
4995 return -1;
4996
4997 if (readbuf == NULL)
a73c6dcd 4998 error (_("tfile_xfer_partial: trace file is read-only"));
00bf0b85 4999
e6e4e701 5000 if (traceframe_number != -1)
00bf0b85 5001 {
ffd5ec24 5002 int pos = 0;
9f41c731 5003
ffd5ec24
PA
5004 /* Iterate through the traceframe's blocks, looking for
5005 memory. */
5006 while ((pos = traceframe_find_block_type ('M', pos)) >= 0)
00bf0b85 5007 {
ffd5ec24
PA
5008 ULONGEST maddr, amt;
5009 unsigned short mlen;
f5656ead 5010 enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch ());
fce3c1f0 5011
ffd5ec24
PA
5012 tfile_read ((gdb_byte *) &maddr, 8);
5013 maddr = extract_unsigned_integer ((gdb_byte *) &maddr, 8,
5014 byte_order);
5015 tfile_read ((gdb_byte *) &mlen, 2);
5016 mlen = (unsigned short)
5017 extract_unsigned_integer ((gdb_byte *) &mlen, 2, byte_order);
5018
5019 /* If the block includes the first part of the desired
5020 range, return as much it has; GDB will re-request the
5021 remainder, which might be in a different block of this
5022 trace frame. */
5023 if (maddr <= offset && offset < (maddr + mlen))
5024 {
5025 amt = (maddr + mlen) - offset;
5026 if (amt > len)
5027 amt = len;
5028
7ecbc825
HZ
5029 if (maddr != offset)
5030 lseek (trace_fd, offset - maddr, SEEK_CUR);
ffd5ec24
PA
5031 tfile_read (readbuf, amt);
5032 return amt;
5033 }
9f41c731 5034
ffd5ec24
PA
5035 /* Skip over this block. */
5036 pos += (8 + 2 + mlen);
5037 }
00bf0b85 5038 }
fce3c1f0
SS
5039
5040 /* It's unduly pedantic to refuse to look at the executable for
5041 read-only pieces; so do the equivalent of readonly regions aka
5042 QTro packet. */
c378eb4e 5043 /* FIXME account for relocation at some point. */
fce3c1f0
SS
5044 if (exec_bfd)
5045 {
5046 asection *s;
5047 bfd_size_type size;
2209c807 5048 bfd_vma vma;
fce3c1f0
SS
5049
5050 for (s = exec_bfd->sections; s; s = s->next)
5051 {
9f41c731
PA
5052 if ((s->flags & SEC_LOAD) == 0
5053 || (s->flags & SEC_READONLY) == 0)
fce3c1f0
SS
5054 continue;
5055
2209c807 5056 vma = s->vma;
fce3c1f0 5057 size = bfd_get_section_size (s);
2209c807 5058 if (vma <= offset && offset < (vma + size))
fce3c1f0 5059 {
9f41c731
PA
5060 ULONGEST amt;
5061
2209c807 5062 amt = (vma + size) - offset;
fce3c1f0
SS
5063 if (amt > len)
5064 amt = len;
5065
5066 amt = bfd_get_section_contents (exec_bfd, s,
2209c807 5067 readbuf, offset - vma, amt);
fce3c1f0
SS
5068 return amt;
5069 }
5070 }
5071 }
5072
00bf0b85
SS
5073 /* Indicate failure to find the requested memory block. */
5074 return -1;
5075}
5076
5077/* Iterate through the blocks of a trace frame, looking for a 'V'
5078 block with a matching tsv number. */
5079
5080static int
5081tfile_get_trace_state_variable_value (int tsvnum, LONGEST *val)
5082{
9f41c731 5083 int pos;
8ddb1965 5084 int found = 0;
00bf0b85 5085
8ddb1965
YQ
5086 /* Iterate over blocks in current frame and find the last 'V'
5087 block in which tsv number is TSVNUM. In one trace frame, there
5088 may be multiple 'V' blocks created for a given trace variable,
5089 and the last matched 'V' block contains the updated value. */
00bf0b85 5090 pos = 0;
9f41c731 5091 while ((pos = traceframe_find_block_type ('V', pos)) >= 0)
00bf0b85 5092 {
9f41c731
PA
5093 int vnum;
5094
5095 tfile_read ((gdb_byte *) &vnum, 4);
5096 vnum = (int) extract_signed_integer ((gdb_byte *) &vnum, 4,
8991e9fa 5097 gdbarch_byte_order
f5656ead 5098 (target_gdbarch ()));
9f41c731
PA
5099 if (tsvnum == vnum)
5100 {
5101 tfile_read ((gdb_byte *) val, 8);
5102 *val = extract_signed_integer ((gdb_byte *) val, 8,
5103 gdbarch_byte_order
f5656ead 5104 (target_gdbarch ()));
8ddb1965 5105 found = 1;
00bf0b85 5106 }
9f41c731 5107 pos += (4 + 8);
00bf0b85 5108 }
9f41c731 5109
8ddb1965 5110 return found;
00bf0b85
SS
5111}
5112
fce3c1f0
SS
5113static int
5114tfile_has_all_memory (struct target_ops *ops)
5115{
5116 return 1;
5117}
5118
00bf0b85
SS
5119static int
5120tfile_has_memory (struct target_ops *ops)
5121{
5122 return 1;
5123}
5124
5125static int
5126tfile_has_stack (struct target_ops *ops)
5127{
ffd5ec24 5128 return traceframe_number != -1;
00bf0b85
SS
5129}
5130
5131static int
5132tfile_has_registers (struct target_ops *ops)
5133{
ffd5ec24 5134 return traceframe_number != -1;
00bf0b85
SS
5135}
5136
b3b9301e
PA
5137/* Callback for traceframe_walk_blocks. Builds a traceframe_info
5138 object for the tfile target's current traceframe. */
5139
5140static int
5141build_traceframe_info (char blocktype, void *data)
5142{
5143 struct traceframe_info *info = data;
5144
5145 switch (blocktype)
5146 {
5147 case 'M':
5148 {
5149 struct mem_range *r;
5150 ULONGEST maddr;
5151 unsigned short mlen;
5152
5153 tfile_read ((gdb_byte *) &maddr, 8);
e83b17ba
HZ
5154 maddr = extract_unsigned_integer ((gdb_byte *) &maddr, 8,
5155 gdbarch_byte_order
5156 (target_gdbarch ()));
b3b9301e 5157 tfile_read ((gdb_byte *) &mlen, 2);
e83b17ba
HZ
5158 mlen = (unsigned short)
5159 extract_unsigned_integer ((gdb_byte *) &mlen,
5160 2, gdbarch_byte_order
5161 (target_gdbarch ()));
b3b9301e
PA
5162
5163 r = VEC_safe_push (mem_range_s, info->memory, NULL);
5164
5165 r->start = maddr;
5166 r->length = mlen;
5167 break;
5168 }
5169 case 'V':
5170 case 'R':
5171 case 'S':
5172 {
5173 break;
5174 }
5175 default:
5176 warning (_("Unhandled trace block type (%d) '%c ' "
5177 "while building trace frame info."),
5178 blocktype, blocktype);
5179 break;
5180 }
5181
5182 return 0;
5183}
5184
5185static struct traceframe_info *
5186tfile_traceframe_info (void)
5187{
5188 struct traceframe_info *info = XCNEW (struct traceframe_info);
5189
5190 traceframe_walk_blocks (build_traceframe_info, 0, info);
5191 return info;
5192}
5193
00bf0b85
SS
5194static void
5195init_tfile_ops (void)
5196{
5197 tfile_ops.to_shortname = "tfile";
5198 tfile_ops.to_longname = "Local trace dump file";
3e43a32a
MS
5199 tfile_ops.to_doc
5200 = "Use a trace file as a target. Specify the filename of the trace file.";
00bf0b85
SS
5201 tfile_ops.to_open = tfile_open;
5202 tfile_ops.to_close = tfile_close;
5203 tfile_ops.to_fetch_registers = tfile_fetch_registers;
5204 tfile_ops.to_xfer_partial = tfile_xfer_partial;
5205 tfile_ops.to_files_info = tfile_files_info;
5206 tfile_ops.to_get_trace_status = tfile_get_trace_status;
f196051f 5207 tfile_ops.to_get_tracepoint_status = tfile_get_tracepoint_status;
00bf0b85 5208 tfile_ops.to_trace_find = tfile_trace_find;
3e43a32a
MS
5209 tfile_ops.to_get_trace_state_variable_value
5210 = tfile_get_trace_state_variable_value;
00bf0b85 5211 tfile_ops.to_stratum = process_stratum;
fce3c1f0 5212 tfile_ops.to_has_all_memory = tfile_has_all_memory;
00bf0b85
SS
5213 tfile_ops.to_has_memory = tfile_has_memory;
5214 tfile_ops.to_has_stack = tfile_has_stack;
5215 tfile_ops.to_has_registers = tfile_has_registers;
b3b9301e 5216 tfile_ops.to_traceframe_info = tfile_traceframe_info;
00bf0b85
SS
5217 tfile_ops.to_magic = OPS_MAGIC;
5218}
5219
5808517f
YQ
5220void
5221free_current_marker (void *arg)
5222{
5223 struct static_tracepoint_marker **marker_p = arg;
5224
5225 if (*marker_p != NULL)
5226 {
5227 release_static_tracepoint_marker (*marker_p);
5228 xfree (*marker_p);
5229 }
5230 else
5231 *marker_p = NULL;
5232}
5233
0fb4aa4b
PA
5234/* Given a line of text defining a static tracepoint marker, parse it
5235 into a "static tracepoint marker" object. Throws an error is
5236 parsing fails. If PP is non-null, it points to one past the end of
5237 the parsed marker definition. */
5238
5239void
5240parse_static_tracepoint_marker_definition (char *line, char **pp,
5241 struct static_tracepoint_marker *marker)
5242{
5243 char *p, *endp;
5244 ULONGEST addr;
5245 int end;
5246
5247 p = line;
5248 p = unpack_varlen_hex (p, &addr);
5249 p++; /* skip a colon */
5250
f5656ead 5251 marker->gdbarch = target_gdbarch ();
0fb4aa4b
PA
5252 marker->address = (CORE_ADDR) addr;
5253
5254 endp = strchr (p, ':');
5255 if (endp == NULL)
74232302 5256 error (_("bad marker definition: %s"), line);
0fb4aa4b
PA
5257
5258 marker->str_id = xmalloc (endp - p + 1);
5259 end = hex2bin (p, (gdb_byte *) marker->str_id, (endp - p + 1) / 2);
5260 marker->str_id[end] = '\0';
5261
5262 p += 2 * end;
5263 p++; /* skip a colon */
5264
5265 marker->extra = xmalloc (strlen (p) + 1);
5266 end = hex2bin (p, (gdb_byte *) marker->extra, strlen (p) / 2);
5267 marker->extra[end] = '\0';
5268
5269 if (pp)
5270 *pp = p;
5271}
5272
5273/* Release a static tracepoint marker's contents. Note that the
5274 object itself isn't released here. There objects are usually on
5275 the stack. */
5276
5277void
5278release_static_tracepoint_marker (struct static_tracepoint_marker *marker)
5279{
5280 xfree (marker->str_id);
5281 marker->str_id = NULL;
5282}
5283
5284/* Print MARKER to gdb_stdout. */
5285
5286static void
5287print_one_static_tracepoint_marker (int count,
5288 struct static_tracepoint_marker *marker)
5289{
5290 struct command_line *l;
5291 struct symbol *sym;
5292
5293 char wrap_indent[80];
5294 char extra_field_indent[80];
79a45e25 5295 struct ui_out *uiout = current_uiout;
0fb4aa4b
PA
5296 struct cleanup *bkpt_chain;
5297 VEC(breakpoint_p) *tracepoints;
5298
5299 struct symtab_and_line sal;
5300
5301 init_sal (&sal);
5302
5303 sal.pc = marker->address;
5304
5305 tracepoints = static_tracepoints_here (marker->address);
5306
5307 bkpt_chain = make_cleanup_ui_out_tuple_begin_end (uiout, "marker");
5308
5309 /* A counter field to help readability. This is not a stable
5310 identifier! */
5311 ui_out_field_int (uiout, "count", count);
5312
5313 ui_out_field_string (uiout, "marker-id", marker->str_id);
5314
5315 ui_out_field_fmt (uiout, "enabled", "%c",
5316 !VEC_empty (breakpoint_p, tracepoints) ? 'y' : 'n');
5317 ui_out_spaces (uiout, 2);
5318
5319 strcpy (wrap_indent, " ");
5320
5321 if (gdbarch_addr_bit (marker->gdbarch) <= 32)
5322 strcat (wrap_indent, " ");
5323 else
5324 strcat (wrap_indent, " ");
5325
5326 strcpy (extra_field_indent, " ");
5327
5328 ui_out_field_core_addr (uiout, "addr", marker->gdbarch, marker->address);
5329
5330 sal = find_pc_line (marker->address, 0);
5331 sym = find_pc_sect_function (marker->address, NULL);
5332 if (sym)
5333 {
5334 ui_out_text (uiout, "in ");
5335 ui_out_field_string (uiout, "func",
5336 SYMBOL_PRINT_NAME (sym));
5337 ui_out_wrap_hint (uiout, wrap_indent);
5338 ui_out_text (uiout, " at ");
5339 }
5340 else
5341 ui_out_field_skip (uiout, "func");
5342
5343 if (sal.symtab != NULL)
5344 {
05cba821
JK
5345 ui_out_field_string (uiout, "file",
5346 symtab_to_filename_for_display (sal.symtab));
0fb4aa4b
PA
5347 ui_out_text (uiout, ":");
5348
5349 if (ui_out_is_mi_like_p (uiout))
5350 {
0b0865da 5351 const char *fullname = symtab_to_fullname (sal.symtab);
0fb4aa4b 5352
f35a17b5 5353 ui_out_field_string (uiout, "fullname", fullname);
0fb4aa4b
PA
5354 }
5355 else
5356 ui_out_field_skip (uiout, "fullname");
5357
5358 ui_out_field_int (uiout, "line", sal.line);
5359 }
5360 else
5361 {
5362 ui_out_field_skip (uiout, "fullname");
5363 ui_out_field_skip (uiout, "line");
5364 }
5365
5366 ui_out_text (uiout, "\n");
5367 ui_out_text (uiout, extra_field_indent);
5368 ui_out_text (uiout, _("Data: \""));
5369 ui_out_field_string (uiout, "extra-data", marker->extra);
5370 ui_out_text (uiout, "\"\n");
5371
5372 if (!VEC_empty (breakpoint_p, tracepoints))
5373 {
5374 struct cleanup *cleanup_chain;
5375 int ix;
5376 struct breakpoint *b;
5377
5378 cleanup_chain = make_cleanup_ui_out_tuple_begin_end (uiout,
5379 "tracepoints-at");
5380
5381 ui_out_text (uiout, extra_field_indent);
5382 ui_out_text (uiout, _("Probed by static tracepoints: "));
5383 for (ix = 0; VEC_iterate(breakpoint_p, tracepoints, ix, b); ix++)
5384 {
5385 if (ix > 0)
5386 ui_out_text (uiout, ", ");
5387 ui_out_text (uiout, "#");
5388 ui_out_field_int (uiout, "tracepoint-id", b->number);
5389 }
5390
5391 do_cleanups (cleanup_chain);
5392
5393 if (ui_out_is_mi_like_p (uiout))
5394 ui_out_field_int (uiout, "number-of-tracepoints",
5395 VEC_length(breakpoint_p, tracepoints));
5396 else
5397 ui_out_text (uiout, "\n");
5398 }
5399 VEC_free (breakpoint_p, tracepoints);
5400
5401 do_cleanups (bkpt_chain);
0fb4aa4b
PA
5402}
5403
5404static void
5405info_static_tracepoint_markers_command (char *arg, int from_tty)
5406{
5407 VEC(static_tracepoint_marker_p) *markers;
5408 struct cleanup *old_chain;
5409 struct static_tracepoint_marker *marker;
79a45e25 5410 struct ui_out *uiout = current_uiout;
0fb4aa4b
PA
5411 int i;
5412
d1feda86
YQ
5413 /* We don't have to check target_can_use_agent and agent's capability on
5414 static tracepoint here, in order to be compatible with older GDBserver.
5415 We don't check USE_AGENT is true or not, because static tracepoints
5416 don't work without in-process agent, so we don't bother users to type
5417 `set agent on' when to use static tracepoint. */
5418
0fb4aa4b
PA
5419 old_chain
5420 = make_cleanup_ui_out_table_begin_end (uiout, 5, -1,
5421 "StaticTracepointMarkersTable");
5422
5423 ui_out_table_header (uiout, 7, ui_left, "counter", "Cnt");
5424
5425 ui_out_table_header (uiout, 40, ui_left, "marker-id", "ID");
5426
5427 ui_out_table_header (uiout, 3, ui_left, "enabled", "Enb");
f5656ead 5428 if (gdbarch_addr_bit (target_gdbarch ()) <= 32)
0fb4aa4b
PA
5429 ui_out_table_header (uiout, 10, ui_left, "addr", "Address");
5430 else
5431 ui_out_table_header (uiout, 18, ui_left, "addr", "Address");
5432 ui_out_table_header (uiout, 40, ui_noalign, "what", "What");
5433
5434 ui_out_table_body (uiout);
5435
5436 markers = target_static_tracepoint_markers_by_strid (NULL);
5437 make_cleanup (VEC_cleanup (static_tracepoint_marker_p), &markers);
5438
5439 for (i = 0;
5440 VEC_iterate (static_tracepoint_marker_p,
5441 markers, i, marker);
5442 i++)
5443 {
5444 print_one_static_tracepoint_marker (i + 1, marker);
5445 release_static_tracepoint_marker (marker);
5446 }
5447
5448 do_cleanups (old_chain);
5449}
5450
5451/* The $_sdata convenience variable is a bit special. We don't know
5452 for sure type of the value until we actually have a chance to fetch
5453 the data --- the size of the object depends on what has been
5454 collected. We solve this by making $_sdata be an internalvar that
5455 creates a new value on access. */
5456
5457/* Return a new value with the correct type for the sdata object of
5458 the current trace frame. Return a void value if there's no object
5459 available. */
5460
5461static struct value *
22d2b532
SDJ
5462sdata_make_value (struct gdbarch *gdbarch, struct internalvar *var,
5463 void *ignore)
0fb4aa4b
PA
5464{
5465 LONGEST size;
5466 gdb_byte *buf;
5467
5468 /* We need to read the whole object before we know its size. */
5469 size = target_read_alloc (&current_target,
5470 TARGET_OBJECT_STATIC_TRACE_DATA,
5471 NULL, &buf);
5472 if (size >= 0)
5473 {
5474 struct value *v;
5475 struct type *type;
5476
5477 type = init_vector_type (builtin_type (gdbarch)->builtin_true_char,
5478 size);
5479 v = allocate_value (type);
5480 memcpy (value_contents_raw (v), buf, size);
5481 xfree (buf);
5482 return v;
5483 }
5484 else
5485 return allocate_value (builtin_type (gdbarch)->builtin_void);
5486}
5487
b3b9301e
PA
5488#if !defined(HAVE_LIBEXPAT)
5489
5490struct traceframe_info *
5491parse_traceframe_info (const char *tframe_info)
5492{
5493 static int have_warned;
5494
5495 if (!have_warned)
5496 {
5497 have_warned = 1;
5498 warning (_("Can not parse XML trace frame info; XML support "
5499 "was disabled at compile time"));
5500 }
5501
5502 return NULL;
5503}
5504
5505#else /* HAVE_LIBEXPAT */
5506
5507#include "xml-support.h"
5508
5509/* Handle the start of a <memory> element. */
5510
5511static void
5512traceframe_info_start_memory (struct gdb_xml_parser *parser,
5513 const struct gdb_xml_element *element,
5514 void *user_data, VEC(gdb_xml_value_s) *attributes)
5515{
5516 struct traceframe_info *info = user_data;
5517 struct mem_range *r = VEC_safe_push (mem_range_s, info->memory, NULL);
5518 ULONGEST *start_p, *length_p;
5519
5520 start_p = xml_find_attribute (attributes, "start")->value;
5521 length_p = xml_find_attribute (attributes, "length")->value;
5522
5523 r->start = *start_p;
5524 r->length = *length_p;
5525}
5526
5527/* Discard the constructed trace frame info (if an error occurs). */
5528
5529static void
5530free_result (void *p)
5531{
5532 struct traceframe_info *result = p;
5533
5534 free_traceframe_info (result);
5535}
5536
5537/* The allowed elements and attributes for an XML memory map. */
5538
5539static const struct gdb_xml_attribute memory_attributes[] = {
5540 { "start", GDB_XML_AF_NONE, gdb_xml_parse_attr_ulongest, NULL },
5541 { "length", GDB_XML_AF_NONE, gdb_xml_parse_attr_ulongest, NULL },
5542 { NULL, GDB_XML_AF_NONE, NULL, NULL }
5543};
5544
5545static const struct gdb_xml_element traceframe_info_children[] = {
5546 { "memory", memory_attributes, NULL,
5547 GDB_XML_EF_REPEATABLE | GDB_XML_EF_OPTIONAL,
5548 traceframe_info_start_memory, NULL },
5549 { NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL }
5550};
5551
5552static const struct gdb_xml_element traceframe_info_elements[] = {
5553 { "traceframe-info", NULL, traceframe_info_children, GDB_XML_EF_NONE,
5554 NULL, NULL },
5555 { NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL }
5556};
5557
5558/* Parse a traceframe-info XML document. */
5559
5560struct traceframe_info *
5561parse_traceframe_info (const char *tframe_info)
5562{
5563 struct traceframe_info *result;
5564 struct cleanup *back_to;
5565
5566 result = XCNEW (struct traceframe_info);
5567 back_to = make_cleanup (free_result, result);
5568
5569 if (gdb_xml_parse_quick (_("trace frame info"),
5570 "traceframe-info.dtd", traceframe_info_elements,
5571 tframe_info, result) == 0)
5572 {
5573 /* Parsed successfully, keep the result. */
5574 discard_cleanups (back_to);
5575
5576 return result;
5577 }
5578
5579 do_cleanups (back_to);
5580 return NULL;
5581}
5582
5583#endif /* HAVE_LIBEXPAT */
5584
5585/* Returns the traceframe_info object for the current traceframe.
5586 This is where we avoid re-fetching the object from the target if we
5587 already have it cached. */
5588
70221824 5589static struct traceframe_info *
b3b9301e
PA
5590get_traceframe_info (void)
5591{
5592 if (traceframe_info == NULL)
5593 traceframe_info = target_traceframe_info ();
5594
5595 return traceframe_info;
5596}
5597
c0f61f9c
PA
5598/* If the target supports the query, return in RESULT the set of
5599 collected memory in the current traceframe, found within the LEN
5600 bytes range starting at MEMADDR. Returns true if the target
5601 supports the query, otherwise returns false, and RESULT is left
5602 undefined. */
2a7498d8
PA
5603
5604int
5605traceframe_available_memory (VEC(mem_range_s) **result,
5606 CORE_ADDR memaddr, ULONGEST len)
5607{
5608 struct traceframe_info *info = get_traceframe_info ();
5609
5610 if (info != NULL)
5611 {
5612 struct mem_range *r;
5613 int i;
5614
5615 *result = NULL;
5616
5617 for (i = 0; VEC_iterate (mem_range_s, info->memory, i, r); i++)
5618 if (mem_ranges_overlap (r->start, r->length, memaddr, len))
5619 {
5620 ULONGEST lo1, hi1, lo2, hi2;
5621 struct mem_range *nr;
5622
5623 lo1 = memaddr;
5624 hi1 = memaddr + len;
5625
5626 lo2 = r->start;
5627 hi2 = r->start + r->length;
5628
5629 nr = VEC_safe_push (mem_range_s, *result, NULL);
5630
5631 nr->start = max (lo1, lo2);
5632 nr->length = min (hi1, hi2) - nr->start;
5633 }
5634
5635 normalize_mem_ranges (*result);
5636 return 1;
5637 }
5638
5639 return 0;
5640}
5641
22d2b532
SDJ
5642/* Implementation of `sdata' variable. */
5643
5644static const struct internalvar_funcs sdata_funcs =
5645{
5646 sdata_make_value,
5647 NULL,
5648 NULL
5649};
5650
c906108c
SS
5651/* module initialization */
5652void
fba45db2 5653_initialize_tracepoint (void)
c906108c 5654{
fa58ee11
EZ
5655 struct cmd_list_element *c;
5656
0fb4aa4b
PA
5657 /* Explicitly create without lookup, since that tries to create a
5658 value with a void typed value, and when we get here, gdbarch
5659 isn't initialized yet. At this point, we're quite sure there
5660 isn't another convenience variable of the same name. */
22d2b532 5661 create_internalvar_type_lazy ("_sdata", &sdata_funcs, NULL);
0fb4aa4b 5662
c906108c
SS
5663 traceframe_number = -1;
5664 tracepoint_number = -1;
5665
c906108c
SS
5666 if (tracepoint_list.list == NULL)
5667 {
5668 tracepoint_list.listsize = 128;
c5aa993b 5669 tracepoint_list.list = xmalloc
c906108c
SS
5670 (tracepoint_list.listsize * sizeof (struct memrange));
5671 }
5672 if (tracepoint_list.aexpr_list == NULL)
5673 {
5674 tracepoint_list.aexpr_listsize = 128;
5675 tracepoint_list.aexpr_list = xmalloc
5676 (tracepoint_list.aexpr_listsize * sizeof (struct agent_expr *));
5677 }
5678
5679 if (stepping_list.list == NULL)
5680 {
5681 stepping_list.listsize = 128;
c5aa993b 5682 stepping_list.list = xmalloc
c906108c
SS
5683 (stepping_list.listsize * sizeof (struct memrange));
5684 }
5685
5686 if (stepping_list.aexpr_list == NULL)
5687 {
5688 stepping_list.aexpr_listsize = 128;
5689 stepping_list.aexpr_list = xmalloc
5690 (stepping_list.aexpr_listsize * sizeof (struct agent_expr *));
5691 }
5692
c5aa993b 5693 add_info ("scope", scope_info,
1bedd215 5694 _("List the variables local to a scope"));
c906108c 5695
e00d1dc8 5696 add_cmd ("tracepoints", class_trace, NULL,
1a966eab 5697 _("Tracing of program execution without stopping the program."),
c906108c
SS
5698 &cmdlist);
5699
c5aa993b 5700 add_com ("tdump", class_trace, trace_dump_command,
1bedd215 5701 _("Print everything collected at the current tracepoint."));
c906108c 5702
00bf0b85
SS
5703 add_com ("tsave", class_trace, trace_save_command, _("\
5704Save the trace data to a file.\n\
d0353e76 5705Use the '-ctf' option to save the data to CTF format.\n\
00bf0b85
SS
5706Use the '-r' option to direct the target to save directly to the file,\n\
5707using its own filesystem."));
5708
f61e138d
SS
5709 c = add_com ("tvariable", class_trace, trace_variable_command,_("\
5710Define a trace state variable.\n\
5711Argument is a $-prefixed name, optionally followed\n\
5712by '=' and an expression that sets the initial value\n\
5713at the start of tracing."));
5714 set_cmd_completer (c, expression_completer);
5715
5716 add_cmd ("tvariable", class_trace, delete_trace_variable_command, _("\
5717Delete one or more trace state variables.\n\
5718Arguments are the names of the variables to delete.\n\
5719If no arguments are supplied, delete all variables."), &deletelist);
c378eb4e 5720 /* FIXME add a trace variable completer. */
f61e138d
SS
5721
5722 add_info ("tvariables", tvariables_info, _("\
5723Status of trace state variables and their values.\n\
0fb4aa4b
PA
5724"));
5725
5726 add_info ("static-tracepoint-markers",
5727 info_static_tracepoint_markers_command, _("\
5728List target static tracepoints markers.\n\
f61e138d
SS
5729"));
5730
1bedd215
AC
5731 add_prefix_cmd ("tfind", class_trace, trace_find_command, _("\
5732Select a trace frame;\n\
5733No argument means forward by one frame; '-' means backward by one frame."),
c906108c
SS
5734 &tfindlist, "tfind ", 1, &cmdlist);
5735
1a966eab 5736 add_cmd ("outside", class_trace, trace_find_outside_command, _("\
081dfbf7 5737Select a trace frame whose PC is outside the given range (exclusive).\n\
1a966eab 5738Usage: tfind outside addr1, addr2"),
c906108c
SS
5739 &tfindlist);
5740
1a966eab 5741 add_cmd ("range", class_trace, trace_find_range_command, _("\
081dfbf7 5742Select a trace frame whose PC is in the given range (inclusive).\n\
1a966eab 5743Usage: tfind range addr1,addr2"),
c906108c
SS
5744 &tfindlist);
5745
1a966eab
AC
5746 add_cmd ("line", class_trace, trace_find_line_command, _("\
5747Select a trace frame by source line.\n\
cce7e648 5748Argument can be a line number (with optional source file),\n\
c906108c 5749a function name, or '*' followed by an address.\n\
1a966eab 5750Default argument is 'the next source line that was traced'."),
c906108c
SS
5751 &tfindlist);
5752
1a966eab
AC
5753 add_cmd ("tracepoint", class_trace, trace_find_tracepoint_command, _("\
5754Select a trace frame by tracepoint number.\n\
5755Default is the tracepoint for the current trace frame."),
c906108c
SS
5756 &tfindlist);
5757
1a966eab
AC
5758 add_cmd ("pc", class_trace, trace_find_pc_command, _("\
5759Select a trace frame by PC.\n\
5760Default is the current PC, or the PC of the current trace frame."),
c906108c
SS
5761 &tfindlist);
5762
1a966eab 5763 add_cmd ("end", class_trace, trace_find_end_command, _("\
1a966eab 5764De-select any trace frame and resume 'live' debugging."),
c906108c
SS
5765 &tfindlist);
5766
8acc4065 5767 add_alias_cmd ("none", "end", class_trace, 0, &tfindlist);
c906108c
SS
5768
5769 add_cmd ("start", class_trace, trace_find_start_command,
1a966eab 5770 _("Select the first trace frame in the trace buffer."),
c906108c
SS
5771 &tfindlist);
5772
c5aa993b 5773 add_com ("tstatus", class_trace, trace_status_command,
1bedd215 5774 _("Display the status of the current trace data collection."));
c906108c 5775
f196051f
SS
5776 add_com ("tstop", class_trace, trace_stop_command, _("\
5777Stop trace data collection.\n\
5778Usage: tstop [ <notes> ... ]\n\
5779Any arguments supplied are recorded with the trace as a stop reason and\n\
5780reported by tstatus (if the target supports trace notes)."));
c906108c 5781
f196051f
SS
5782 add_com ("tstart", class_trace, trace_start_command, _("\
5783Start trace data collection.\n\
5784Usage: tstart [ <notes> ... ]\n\
5785Any arguments supplied are recorded with the trace as a note and\n\
5786reported by tstatus (if the target supports trace notes)."));
c906108c 5787
1bedd215
AC
5788 add_com ("end", class_trace, end_actions_pseudocommand, _("\
5789Ends a list of commands or actions.\n\
c906108c
SS
5790Several GDB commands allow you to enter a list of commands or actions.\n\
5791Entering \"end\" on a line by itself is the normal way to terminate\n\
5792such a list.\n\n\
1bedd215 5793Note: the \"end\" command cannot be used at the gdb prompt."));
c906108c 5794
1bedd215
AC
5795 add_com ("while-stepping", class_trace, while_stepping_pseudocommand, _("\
5796Specify single-stepping behavior at a tracepoint.\n\
c906108c
SS
5797Argument is number of instructions to trace in single-step mode\n\
5798following the tracepoint. This command is normally followed by\n\
5799one or more \"collect\" commands, to specify what to collect\n\
5800while single-stepping.\n\n\
1bedd215 5801Note: this command can only be used in a tracepoint \"actions\" list."));
c906108c 5802
c5aa993b
JM
5803 add_com_alias ("ws", "while-stepping", class_alias, 0);
5804 add_com_alias ("stepping", "while-stepping", class_alias, 0);
c906108c 5805
1bedd215
AC
5806 add_com ("collect", class_trace, collect_pseudocommand, _("\
5807Specify one or more data items to be collected at a tracepoint.\n\
c906108c
SS
5808Accepts a comma-separated list of (one or more) expressions. GDB will\n\
5809collect all data (variables, registers) referenced by that expression.\n\
5810Also accepts the following special arguments:\n\
5811 $regs -- all registers.\n\
5812 $args -- all function arguments.\n\
5813 $locals -- all variables local to the block/function scope.\n\
0fb4aa4b 5814 $_sdata -- static tracepoint data (ignored for non-static tracepoints).\n\
1bedd215 5815Note: this command can only be used in a tracepoint \"actions\" list."));
c906108c 5816
6da95a67
SS
5817 add_com ("teval", class_trace, teval_pseudocommand, _("\
5818Specify one or more expressions to be evaluated at a tracepoint.\n\
5819Accepts a comma-separated list of (one or more) expressions.\n\
5820The result of each evaluation will be discarded.\n\
5821Note: this command can only be used in a tracepoint \"actions\" list."));
5822
1bedd215
AC
5823 add_com ("actions", class_trace, trace_actions_command, _("\
5824Specify the actions to be taken at a tracepoint.\n\
cce7e648
PA
5825Tracepoint actions may include collecting of specified data,\n\
5826single-stepping, or enabling/disabling other tracepoints,\n\
1bedd215 5827depending on target's capabilities."));
c906108c 5828
236f1d4d
SS
5829 default_collect = xstrdup ("");
5830 add_setshow_string_cmd ("default-collect", class_trace,
5831 &default_collect, _("\
5832Set the list of expressions to collect by default"), _("\
5833Show the list of expressions to collect by default"), NULL,
5834 NULL, NULL,
5835 &setlist, &showlist);
5836
d5551862
SS
5837 add_setshow_boolean_cmd ("disconnected-tracing", no_class,
5838 &disconnected_tracing, _("\
5839Set whether tracing continues after GDB disconnects."), _("\
5840Show whether tracing continues after GDB disconnects."), _("\
5841Use this to continue a tracing run even if GDB disconnects\n\
5842or detaches from the target. You can reconnect later and look at\n\
5843trace data collected in the meantime."),
5844 set_disconnected_tracing,
5845 NULL,
5846 &setlist,
5847 &showlist);
00bf0b85 5848
4daf5ac0
SS
5849 add_setshow_boolean_cmd ("circular-trace-buffer", no_class,
5850 &circular_trace_buffer, _("\
5851Set target's use of circular trace buffer."), _("\
5852Show target's use of circular trace buffer."), _("\
5853Use this to make the trace buffer into a circular buffer,\n\
5854which will discard traceframes (oldest first) instead of filling\n\
5855up and stopping the trace run."),
5856 set_circular_trace_buffer,
5857 NULL,
5858 &setlist,
5859 &showlist);
5860
f6f899bf 5861 add_setshow_zuinteger_unlimited_cmd ("trace-buffer-size", no_class,
9b67fcec 5862 &trace_buffer_size, _("\
f6f899bf
HAQ
5863Set requested size of trace buffer."), _("\
5864Show requested size of trace buffer."), _("\
5865Use this to choose a size for the trace buffer. Some targets\n\
f81d1120
PA
5866may have fixed or limited buffer sizes. Specifying \"unlimited\" or -1\n\
5867disables any attempt to set the buffer size and lets the target choose."),
9b67fcec
YQ
5868 set_trace_buffer_size, NULL,
5869 &setlist, &showlist);
f6f899bf 5870
f196051f
SS
5871 add_setshow_string_cmd ("trace-user", class_trace,
5872 &trace_user, _("\
5873Set the user name to use for current and future trace runs"), _("\
5874Show the user name to use for current and future trace runs"), NULL,
5875 set_trace_user, NULL,
5876 &setlist, &showlist);
5877
5878 add_setshow_string_cmd ("trace-notes", class_trace,
5879 &trace_notes, _("\
5880Set notes string to use for current and future trace runs"), _("\
5881Show the notes string to use for current and future trace runs"), NULL,
5882 set_trace_notes, NULL,
5883 &setlist, &showlist);
5884
5885 add_setshow_string_cmd ("trace-stop-notes", class_trace,
5886 &trace_stop_notes, _("\
5887Set notes string to use for future tstop commands"), _("\
5888Show the notes string to use for future tstop commands"), NULL,
5889 set_trace_stop_notes, NULL,
5890 &setlist, &showlist);
5891
00bf0b85
SS
5892 init_tfile_ops ();
5893
9852c492 5894 add_target_with_completer (&tfile_ops, filename_completer);
c906108c 5895}
This page took 1.93512 seconds and 4 git commands to generate.