OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [gdb-5.3/] [gdb/] [tracepoint.c] - Blame information for rev 1773

Go to most recent revision | Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.