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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [insight/] [gdb/] [tracepoint.c] - Blame information for rev 1771

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

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

powered by: WebSVN 2.1.0

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