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