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