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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-stable/] [gdb-7.2/] [gdb/] [record.c] - Blame information for rev 841

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 330 jeremybenn
/* Process record and replay target for GDB, the GNU debugger.
2
 
3
   Copyright (C) 2008, 2009, 2010 Free Software Foundation, Inc.
4
 
5
   This file is part of GDB.
6
 
7
   This program is free software; you can redistribute it and/or modify
8
   it under the terms of the GNU General Public License as published by
9
   the Free Software Foundation; either version 3 of the License, or
10
   (at your option) any later version.
11
 
12
   This program is distributed in the hope that it will be useful,
13
   but WITHOUT ANY WARRANTY; without even the implied warranty of
14
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
   GNU General Public License for more details.
16
 
17
   You should have received a copy of the GNU General Public License
18
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
19
 
20
#include "defs.h"
21
#include "gdbcmd.h"
22
#include "regcache.h"
23
#include "gdbthread.h"
24
#include "event-top.h"
25
#include "exceptions.h"
26
#include "completer.h"
27
#include "arch-utils.h"
28
#include "gdbcore.h"
29
#include "exec.h"
30
#include "record.h"
31
#include "elf-bfd.h"
32
#include "gcore.h"
33
 
34
#include <signal.h>
35
 
36
/* This module implements "target record", also known as "process
37
   record and replay".  This target sits on top of a "normal" target
38
   (a target that "has execution"), and provides a record and replay
39
   functionality, including reverse debugging.
40
 
41
   Target record has two modes: recording, and replaying.
42
 
43
   In record mode, we intercept the to_resume and to_wait methods.
44
   Whenever gdb resumes the target, we run the target in single step
45
   mode, and we build up an execution log in which, for each executed
46
   instruction, we record all changes in memory and register state.
47
   This is invisible to the user, to whom it just looks like an
48
   ordinary debugging session (except for performance degredation).
49
 
50
   In replay mode, instead of actually letting the inferior run as a
51
   process, we simulate its execution by playing back the recorded
52
   execution log.  For each instruction in the log, we simulate the
53
   instruction's side effects by duplicating the changes that it would
54
   have made on memory and registers.  */
55
 
56
#define DEFAULT_RECORD_INSN_MAX_NUM     200000
57
 
58
#define RECORD_IS_REPLAY \
59
     (record_list->next || execution_direction == EXEC_REVERSE)
60
 
61
#define RECORD_FILE_MAGIC       netorder32(0x20091016)
62
 
63
/* These are the core structs of the process record functionality.
64
 
65
   A record_entry is a record of the value change of a register
66
   ("record_reg") or a part of memory ("record_mem").  And each
67
   instruction must have a struct record_entry ("record_end") that
68
   indicates that this is the last struct record_entry of this
69
   instruction.
70
 
71
   Each struct record_entry is linked to "record_list" by "prev" and
72
   "next" pointers.  */
73
 
74
struct record_mem_entry
75
{
76
  CORE_ADDR addr;
77
  int len;
78
  /* Set this flag if target memory for this entry
79
     can no longer be accessed.  */
80
  int mem_entry_not_accessible;
81
  union
82
  {
83
    gdb_byte *ptr;
84
    gdb_byte buf[sizeof (gdb_byte *)];
85
  } u;
86
};
87
 
88
struct record_reg_entry
89
{
90
  unsigned short num;
91
  unsigned short len;
92
  union
93
  {
94
    gdb_byte *ptr;
95
    gdb_byte buf[2 * sizeof (gdb_byte *)];
96
  } u;
97
};
98
 
99
struct record_end_entry
100
{
101
  enum target_signal sigval;
102
  ULONGEST insn_num;
103
};
104
 
105
enum record_type
106
{
107
  record_end = 0,
108
  record_reg,
109
  record_mem
110
};
111
 
112
/* This is the data structure that makes up the execution log.
113
 
114
   The execution log consists of a single linked list of entries
115
   of type "struct record_entry".  It is doubly linked so that it
116
   can be traversed in either direction.
117
 
118
   The start of the list is anchored by a struct called
119
   "record_first".  The pointer "record_list" either points to the
120
   last entry that was added to the list (in record mode), or to the
121
   next entry in the list that will be executed (in replay mode).
122
 
123
   Each list element (struct record_entry), in addition to next and
124
   prev pointers, consists of a union of three entry types: mem, reg,
125
   and end.  A field called "type" determines which entry type is
126
   represented by a given list element.
127
 
128
   Each instruction that is added to the execution log is represented
129
   by a variable number of list elements ('entries').  The instruction
130
   will have one "reg" entry for each register that is changed by
131
   executing the instruction (including the PC in every case).  It
132
   will also have one "mem" entry for each memory change.  Finally,
133
   each instruction will have an "end" entry that separates it from
134
   the changes associated with the next instruction.  */
135
 
136
struct record_entry
137
{
138
  struct record_entry *prev;
139
  struct record_entry *next;
140
  enum record_type type;
141
  union
142
  {
143
    /* reg */
144
    struct record_reg_entry reg;
145
    /* mem */
146
    struct record_mem_entry mem;
147
    /* end */
148
    struct record_end_entry end;
149
  } u;
150
};
151
 
152
/* This is the debug switch for process record.  */
153
int record_debug = 0;
154
 
155
/* If true, query if PREC cannot record memory
156
   change of next instruction.  */
157
int record_memory_query = 0;
158
 
159
struct record_core_buf_entry
160
{
161
  struct record_core_buf_entry *prev;
162
  struct target_section *p;
163
  bfd_byte *buf;
164
};
165
 
166
/* Record buf with core target.  */
167
static gdb_byte *record_core_regbuf = NULL;
168
static struct target_section *record_core_start;
169
static struct target_section *record_core_end;
170
static struct record_core_buf_entry *record_core_buf_list = NULL;
171
 
172
/* The following variables are used for managing the linked list that
173
   represents the execution log.
174
 
175
   record_first is the anchor that holds down the beginning of the list.
176
 
177
   record_list serves two functions:
178
     1) In record mode, it anchors the end of the list.
179
     2) In replay mode, it traverses the list and points to
180
        the next instruction that must be emulated.
181
 
182
   record_arch_list_head and record_arch_list_tail are used to manage
183
   a separate list, which is used to build up the change elements of
184
   the currently executing instruction during record mode.  When this
185
   instruction has been completely annotated in the "arch list", it
186
   will be appended to the main execution log.  */
187
 
188
static struct record_entry record_first;
189
static struct record_entry *record_list = &record_first;
190
static struct record_entry *record_arch_list_head = NULL;
191
static struct record_entry *record_arch_list_tail = NULL;
192
 
193
/* 1 ask user. 0 auto delete the last struct record_entry.  */
194
static int record_stop_at_limit = 1;
195
/* Maximum allowed number of insns in execution log.  */
196
static unsigned int record_insn_max_num = DEFAULT_RECORD_INSN_MAX_NUM;
197
/* Actual count of insns presently in execution log.  */
198
static int record_insn_num = 0;
199
/* Count of insns logged so far (may be larger
200
   than count of insns presently in execution log).  */
201
static ULONGEST record_insn_count;
202
 
203
/* The target_ops of process record.  */
204
static struct target_ops record_ops;
205
static struct target_ops record_core_ops;
206
 
207
/* The beneath function pointers.  */
208
static struct target_ops *record_beneath_to_resume_ops;
209
static void (*record_beneath_to_resume) (struct target_ops *, ptid_t, int,
210
                                         enum target_signal);
211
static struct target_ops *record_beneath_to_wait_ops;
212
static ptid_t (*record_beneath_to_wait) (struct target_ops *, ptid_t,
213
                                         struct target_waitstatus *,
214
                                         int);
215
static struct target_ops *record_beneath_to_store_registers_ops;
216
static void (*record_beneath_to_store_registers) (struct target_ops *,
217
                                                  struct regcache *,
218
                                                  int regno);
219
static struct target_ops *record_beneath_to_xfer_partial_ops;
220
static LONGEST (*record_beneath_to_xfer_partial) (struct target_ops *ops,
221
                                                  enum target_object object,
222
                                                  const char *annex,
223
                                                  gdb_byte *readbuf,
224
                                                  const gdb_byte *writebuf,
225
                                                  ULONGEST offset,
226
                                                  LONGEST len);
227
static int (*record_beneath_to_insert_breakpoint) (struct gdbarch *,
228
                                                   struct bp_target_info *);
229
static int (*record_beneath_to_remove_breakpoint) (struct gdbarch *,
230
                                                   struct bp_target_info *);
231
static int (*record_beneath_to_stopped_by_watchpoint) (void);
232
static int (*record_beneath_to_stopped_data_address) (struct target_ops *,
233
                                                      CORE_ADDR *);
234
 
235
/* Alloc and free functions for record_reg, record_mem, and record_end
236
   entries.  */
237
 
238
/* Alloc a record_reg record entry.  */
239
 
240
static inline struct record_entry *
241
record_reg_alloc (struct regcache *regcache, int regnum)
242
{
243
  struct record_entry *rec;
244
  struct gdbarch *gdbarch = get_regcache_arch (regcache);
245
 
246
  rec = (struct record_entry *) xcalloc (1, sizeof (struct record_entry));
247
  rec->type = record_reg;
248
  rec->u.reg.num = regnum;
249
  rec->u.reg.len = register_size (gdbarch, regnum);
250
  if (rec->u.reg.len > sizeof (rec->u.reg.u.buf))
251
    rec->u.reg.u.ptr = (gdb_byte *) xmalloc (rec->u.reg.len);
252
 
253
  return rec;
254
}
255
 
256
/* Free a record_reg record entry.  */
257
 
258
static inline void
259
record_reg_release (struct record_entry *rec)
260
{
261
  gdb_assert (rec->type == record_reg);
262
  if (rec->u.reg.len > sizeof (rec->u.reg.u.buf))
263
    xfree (rec->u.reg.u.ptr);
264
  xfree (rec);
265
}
266
 
267
/* Alloc a record_mem record entry.  */
268
 
269
static inline struct record_entry *
270
record_mem_alloc (CORE_ADDR addr, int len)
271
{
272
  struct record_entry *rec;
273
 
274
  rec = (struct record_entry *) xcalloc (1, sizeof (struct record_entry));
275
  rec->type = record_mem;
276
  rec->u.mem.addr = addr;
277
  rec->u.mem.len = len;
278
  if (rec->u.mem.len > sizeof (rec->u.mem.u.buf))
279
    rec->u.mem.u.ptr = (gdb_byte *) xmalloc (len);
280
 
281
  return rec;
282
}
283
 
284
/* Free a record_mem record entry.  */
285
 
286
static inline void
287
record_mem_release (struct record_entry *rec)
288
{
289
  gdb_assert (rec->type == record_mem);
290
  if (rec->u.mem.len > sizeof (rec->u.mem.u.buf))
291
    xfree (rec->u.mem.u.ptr);
292
  xfree (rec);
293
}
294
 
295
/* Alloc a record_end record entry.  */
296
 
297
static inline struct record_entry *
298
record_end_alloc (void)
299
{
300
  struct record_entry *rec;
301
 
302
  rec = (struct record_entry *) xcalloc (1, sizeof (struct record_entry));
303
  rec->type = record_end;
304
 
305
  return rec;
306
}
307
 
308
/* Free a record_end record entry.  */
309
 
310
static inline void
311
record_end_release (struct record_entry *rec)
312
{
313
  xfree (rec);
314
}
315
 
316
/* Free one record entry, any type.
317
   Return entry->type, in case caller wants to know.  */
318
 
319
static inline enum record_type
320
record_entry_release (struct record_entry *rec)
321
{
322
  enum record_type type = rec->type;
323
 
324
  switch (type) {
325
  case record_reg:
326
    record_reg_release (rec);
327
    break;
328
  case record_mem:
329
    record_mem_release (rec);
330
    break;
331
  case record_end:
332
    record_end_release (rec);
333
    break;
334
  }
335
  return type;
336
}
337
 
338
/* Free all record entries in list pointed to by REC.  */
339
 
340
static void
341
record_list_release (struct record_entry *rec)
342
{
343
  if (!rec)
344
    return;
345
 
346
  while (rec->next)
347
    rec = rec->next;
348
 
349
  while (rec->prev)
350
    {
351
      rec = rec->prev;
352
      record_entry_release (rec->next);
353
    }
354
 
355
  if (rec == &record_first)
356
    {
357
      record_insn_num = 0;
358
      record_first.next = NULL;
359
    }
360
  else
361
    record_entry_release (rec);
362
}
363
 
364
/* Free all record entries forward of the given list position.  */
365
 
366
static void
367
record_list_release_following (struct record_entry *rec)
368
{
369
  struct record_entry *tmp = rec->next;
370
 
371
  rec->next = NULL;
372
  while (tmp)
373
    {
374
      rec = tmp->next;
375
      if (record_entry_release (tmp) == record_end)
376
        {
377
          record_insn_num--;
378
          record_insn_count--;
379
        }
380
      tmp = rec;
381
    }
382
}
383
 
384
/* Delete the first instruction from the beginning of the log, to make
385
   room for adding a new instruction at the end of the log.
386
 
387
   Note -- this function does not modify record_insn_num.  */
388
 
389
static void
390
record_list_release_first (void)
391
{
392
  struct record_entry *tmp;
393
 
394
  if (!record_first.next)
395
    return;
396
 
397
  /* Loop until a record_end.  */
398
  while (1)
399
    {
400
      /* Cut record_first.next out of the linked list.  */
401
      tmp = record_first.next;
402
      record_first.next = tmp->next;
403
      tmp->next->prev = &record_first;
404
 
405
      /* tmp is now isolated, and can be deleted.  */
406
      if (record_entry_release (tmp) == record_end)
407
        break;  /* End loop at first record_end.  */
408
 
409
      if (!record_first.next)
410
        {
411
          gdb_assert (record_insn_num == 1);
412
          break;        /* End loop when list is empty.  */
413
        }
414
    }
415
}
416
 
417
/* Add a struct record_entry to record_arch_list.  */
418
 
419
static void
420
record_arch_list_add (struct record_entry *rec)
421
{
422
  if (record_debug > 1)
423
    fprintf_unfiltered (gdb_stdlog,
424
                        "Process record: record_arch_list_add %s.\n",
425
                        host_address_to_string (rec));
426
 
427
  if (record_arch_list_tail)
428
    {
429
      record_arch_list_tail->next = rec;
430
      rec->prev = record_arch_list_tail;
431
      record_arch_list_tail = rec;
432
    }
433
  else
434
    {
435
      record_arch_list_head = rec;
436
      record_arch_list_tail = rec;
437
    }
438
}
439
 
440
/* Return the value storage location of a record entry.  */
441
static inline gdb_byte *
442
record_get_loc (struct record_entry *rec)
443
{
444
  switch (rec->type) {
445
  case record_mem:
446
    if (rec->u.mem.len > sizeof (rec->u.mem.u.buf))
447
      return rec->u.mem.u.ptr;
448
    else
449
      return rec->u.mem.u.buf;
450
  case record_reg:
451
    if (rec->u.reg.len > sizeof (rec->u.reg.u.buf))
452
      return rec->u.reg.u.ptr;
453
    else
454
      return rec->u.reg.u.buf;
455
  case record_end:
456
  default:
457
    gdb_assert (0);
458
    return NULL;
459
  }
460
}
461
 
462
/* Record the value of a register NUM to record_arch_list.  */
463
 
464
int
465
record_arch_list_add_reg (struct regcache *regcache, int regnum)
466
{
467
  struct record_entry *rec;
468
 
469
  if (record_debug > 1)
470
    fprintf_unfiltered (gdb_stdlog,
471
                        "Process record: add register num = %d to "
472
                        "record list.\n",
473
                        regnum);
474
 
475
  rec = record_reg_alloc (regcache, regnum);
476
 
477
  regcache_raw_read (regcache, regnum, record_get_loc (rec));
478
 
479
  record_arch_list_add (rec);
480
 
481
  return 0;
482
}
483
 
484
/* Record the value of a region of memory whose address is ADDR and
485
   length is LEN to record_arch_list.  */
486
 
487
int
488
record_arch_list_add_mem (CORE_ADDR addr, int len)
489
{
490
  struct record_entry *rec;
491
 
492
  if (record_debug > 1)
493
    fprintf_unfiltered (gdb_stdlog,
494
                        "Process record: add mem addr = %s len = %d to "
495
                        "record list.\n",
496
                        paddress (target_gdbarch, addr), len);
497
 
498
  if (!addr)    /* FIXME: Why?  Some arch must permit it... */
499
    return 0;
500
 
501
  rec = record_mem_alloc (addr, len);
502
 
503
  if (target_read_memory (addr, record_get_loc (rec), len))
504
    {
505
      if (record_debug)
506
        fprintf_unfiltered (gdb_stdlog,
507
                            "Process record: error reading memory at "
508
                            "addr = %s len = %d.\n",
509
                            paddress (target_gdbarch, addr), len);
510
      record_mem_release (rec);
511
      return -1;
512
    }
513
 
514
  record_arch_list_add (rec);
515
 
516
  return 0;
517
}
518
 
519
/* Add a record_end type struct record_entry to record_arch_list.  */
520
 
521
int
522
record_arch_list_add_end (void)
523
{
524
  struct record_entry *rec;
525
 
526
  if (record_debug > 1)
527
    fprintf_unfiltered (gdb_stdlog,
528
                        "Process record: add end to arch list.\n");
529
 
530
  rec = record_end_alloc ();
531
  rec->u.end.sigval = TARGET_SIGNAL_0;
532
  rec->u.end.insn_num = ++record_insn_count;
533
 
534
  record_arch_list_add (rec);
535
 
536
  return 0;
537
}
538
 
539
static void
540
record_check_insn_num (int set_terminal)
541
{
542
  if (record_insn_max_num)
543
    {
544
      gdb_assert (record_insn_num <= record_insn_max_num);
545
      if (record_insn_num == record_insn_max_num)
546
        {
547
          /* Ask user what to do.  */
548
          if (record_stop_at_limit)
549
            {
550
              int q;
551
 
552
              if (set_terminal)
553
                target_terminal_ours ();
554
              q = yquery (_("Do you want to auto delete previous execution "
555
                            "log entries when record/replay buffer becomes "
556
                            "full (record stop-at-limit)?"));
557
              if (set_terminal)
558
                target_terminal_inferior ();
559
              if (q)
560
                record_stop_at_limit = 0;
561
              else
562
                error (_("Process record: stopped by user."));
563
            }
564
        }
565
    }
566
}
567
 
568
static void
569
record_arch_list_cleanups (void *ignore)
570
{
571
  record_list_release (record_arch_list_tail);
572
}
573
 
574
/* Before inferior step (when GDB record the running message, inferior
575
   only can step), GDB will call this function to record the values to
576
   record_list.  This function will call gdbarch_process_record to
577
   record the running message of inferior and set them to
578
   record_arch_list, and add it to record_list.  */
579
 
580
static int
581
record_message (struct regcache *regcache, enum target_signal signal)
582
{
583
  int ret;
584
  struct gdbarch *gdbarch = get_regcache_arch (regcache);
585
  struct cleanup *old_cleanups = make_cleanup (record_arch_list_cleanups, 0);
586
 
587
  record_arch_list_head = NULL;
588
  record_arch_list_tail = NULL;
589
 
590
  /* Check record_insn_num.  */
591
  record_check_insn_num (1);
592
 
593
  /* If gdb sends a signal value to target_resume,
594
     save it in the 'end' field of the previous instruction.
595
 
596
     Maybe process record should record what really happened,
597
     rather than what gdb pretends has happened.
598
 
599
     So if Linux delivered the signal to the child process during
600
     the record mode, we will record it and deliver it again in
601
     the replay mode.
602
 
603
     If user says "ignore this signal" during the record mode, then
604
     it will be ignored again during the replay mode (no matter if
605
     the user says something different, like "deliver this signal"
606
     during the replay mode).
607
 
608
     User should understand that nothing he does during the replay
609
     mode will change the behavior of the child.  If he tries,
610
     then that is a user error.
611
 
612
     But we should still deliver the signal to gdb during the replay,
613
     if we delivered it during the recording.  Therefore we should
614
     record the signal during record_wait, not record_resume.  */
615
  if (record_list != &record_first)    /* FIXME better way to check */
616
    {
617
      gdb_assert (record_list->type == record_end);
618
      record_list->u.end.sigval = signal;
619
    }
620
 
621
  if (signal == TARGET_SIGNAL_0
622
      || !gdbarch_process_record_signal_p (gdbarch))
623
    ret = gdbarch_process_record (gdbarch,
624
                                  regcache,
625
                                  regcache_read_pc (regcache));
626
  else
627
    ret = gdbarch_process_record_signal (gdbarch,
628
                                         regcache,
629
                                         signal);
630
 
631
  if (ret > 0)
632
    error (_("Process record: inferior program stopped."));
633
  if (ret < 0)
634
    error (_("Process record: failed to record execution log."));
635
 
636
  discard_cleanups (old_cleanups);
637
 
638
  record_list->next = record_arch_list_head;
639
  record_arch_list_head->prev = record_list;
640
  record_list = record_arch_list_tail;
641
 
642
  if (record_insn_num == record_insn_max_num && record_insn_max_num)
643
    record_list_release_first ();
644
  else
645
    record_insn_num++;
646
 
647
  return 1;
648
}
649
 
650
struct record_message_args {
651
  struct regcache *regcache;
652
  enum target_signal signal;
653
};
654
 
655
static int
656
record_message_wrapper (void *args)
657
{
658
  struct record_message_args *record_args = args;
659
 
660
  return record_message (record_args->regcache, record_args->signal);
661
}
662
 
663
static int
664
record_message_wrapper_safe (struct regcache *regcache,
665
                             enum target_signal signal)
666
{
667
  struct record_message_args args;
668
 
669
  args.regcache = regcache;
670
  args.signal = signal;
671
 
672
  return catch_errors (record_message_wrapper, &args, NULL, RETURN_MASK_ALL);
673
}
674
 
675
/* Set to 1 if record_store_registers and record_xfer_partial
676
   doesn't need record.  */
677
 
678
static int record_gdb_operation_disable = 0;
679
 
680
struct cleanup *
681
record_gdb_operation_disable_set (void)
682
{
683
  struct cleanup *old_cleanups = NULL;
684
 
685
  old_cleanups =
686
    make_cleanup_restore_integer (&record_gdb_operation_disable);
687
  record_gdb_operation_disable = 1;
688
 
689
  return old_cleanups;
690
}
691
 
692
/* Flag set to TRUE for target_stopped_by_watchpoint.  */
693
static int record_hw_watchpoint = 0;
694
 
695
/* Execute one instruction from the record log.  Each instruction in
696
   the log will be represented by an arbitrary sequence of register
697
   entries and memory entries, followed by an 'end' entry.  */
698
 
699
static inline void
700
record_exec_insn (struct regcache *regcache, struct gdbarch *gdbarch,
701
                  struct record_entry *entry)
702
{
703
  switch (entry->type)
704
    {
705
    case record_reg: /* reg */
706
      {
707
        gdb_byte reg[MAX_REGISTER_SIZE];
708
 
709
        if (record_debug > 1)
710
          fprintf_unfiltered (gdb_stdlog,
711
                              "Process record: record_reg %s to "
712
                              "inferior num = %d.\n",
713
                              host_address_to_string (entry),
714
                              entry->u.reg.num);
715
 
716
        regcache_cooked_read (regcache, entry->u.reg.num, reg);
717
        regcache_cooked_write (regcache, entry->u.reg.num,
718
                               record_get_loc (entry));
719
        memcpy (record_get_loc (entry), reg, entry->u.reg.len);
720
      }
721
      break;
722
 
723
    case record_mem: /* mem */
724
      {
725
        /* Nothing to do if the entry is flagged not_accessible.  */
726
        if (!entry->u.mem.mem_entry_not_accessible)
727
          {
728
            gdb_byte *mem = alloca (entry->u.mem.len);
729
 
730
            if (record_debug > 1)
731
              fprintf_unfiltered (gdb_stdlog,
732
                                  "Process record: record_mem %s to "
733
                                  "inferior addr = %s len = %d.\n",
734
                                  host_address_to_string (entry),
735
                                  paddress (gdbarch, entry->u.mem.addr),
736
                                  entry->u.mem.len);
737
 
738
            if (target_read_memory (entry->u.mem.addr, mem, entry->u.mem.len))
739
              {
740
                entry->u.mem.mem_entry_not_accessible = 1;
741
                if (record_debug)
742
                  warning ("Process record: error reading memory at "
743
                           "addr = %s len = %d.",
744
                           paddress (gdbarch, entry->u.mem.addr),
745
                           entry->u.mem.len);
746
              }
747
            else
748
              {
749
                if (target_write_memory (entry->u.mem.addr,
750
                                         record_get_loc (entry),
751
                                         entry->u.mem.len))
752
                  {
753
                    entry->u.mem.mem_entry_not_accessible = 1;
754
                    if (record_debug)
755
                      warning ("Process record: error writing memory at "
756
                               "addr = %s len = %d.",
757
                               paddress (gdbarch, entry->u.mem.addr),
758
                               entry->u.mem.len);
759
                  }
760
                else
761
                  {
762
                    memcpy (record_get_loc (entry), mem, entry->u.mem.len);
763
 
764
                    /* We've changed memory --- check if a hardware
765
                       watchpoint should trap.  Note that this
766
                       presently assumes the target beneath supports
767
                       continuable watchpoints.  On non-continuable
768
                       watchpoints target, we'll want to check this
769
                       _before_ actually doing the memory change, and
770
                       not doing the change at all if the watchpoint
771
                       traps.  */
772
                    if (hardware_watchpoint_inserted_in_range
773
                        (get_regcache_aspace (regcache),
774
                         entry->u.mem.addr, entry->u.mem.len))
775
                      record_hw_watchpoint = 1;
776
                  }
777
              }
778
          }
779
      }
780
      break;
781
    }
782
}
783
 
784
static struct target_ops *tmp_to_resume_ops;
785
static void (*tmp_to_resume) (struct target_ops *, ptid_t, int,
786
                              enum target_signal);
787
static struct target_ops *tmp_to_wait_ops;
788
static ptid_t (*tmp_to_wait) (struct target_ops *, ptid_t,
789
                              struct target_waitstatus *,
790
                              int);
791
static struct target_ops *tmp_to_store_registers_ops;
792
static void (*tmp_to_store_registers) (struct target_ops *,
793
                                       struct regcache *,
794
                                       int regno);
795
static struct target_ops *tmp_to_xfer_partial_ops;
796
static LONGEST (*tmp_to_xfer_partial) (struct target_ops *ops,
797
                                       enum target_object object,
798
                                       const char *annex,
799
                                       gdb_byte *readbuf,
800
                                       const gdb_byte *writebuf,
801
                                       ULONGEST offset,
802
                                       LONGEST len);
803
static int (*tmp_to_insert_breakpoint) (struct gdbarch *,
804
                                        struct bp_target_info *);
805
static int (*tmp_to_remove_breakpoint) (struct gdbarch *,
806
                                        struct bp_target_info *);
807
static int (*tmp_to_stopped_by_watchpoint) (void);
808
static int (*tmp_to_stopped_data_address) (struct target_ops *, CORE_ADDR *);
809
 
810
static void record_restore (void);
811
 
812
/* Open the process record target.  */
813
 
814
static void
815
record_core_open_1 (char *name, int from_tty)
816
{
817
  struct regcache *regcache = get_current_regcache ();
818
  int regnum = gdbarch_num_regs (get_regcache_arch (regcache));
819
  int i;
820
 
821
  /* Get record_core_regbuf.  */
822
  target_fetch_registers (regcache, -1);
823
  record_core_regbuf = xmalloc (MAX_REGISTER_SIZE * regnum);
824
  for (i = 0; i < regnum; i ++)
825
    regcache_raw_collect (regcache, i,
826
                          record_core_regbuf + MAX_REGISTER_SIZE * i);
827
 
828
  /* Get record_core_start and record_core_end.  */
829
  if (build_section_table (core_bfd, &record_core_start, &record_core_end))
830
    {
831
      xfree (record_core_regbuf);
832
      record_core_regbuf = NULL;
833
      error (_("\"%s\": Can't find sections: %s"),
834
             bfd_get_filename (core_bfd), bfd_errmsg (bfd_get_error ()));
835
    }
836
 
837
  push_target (&record_core_ops);
838
  record_restore ();
839
}
840
 
841
/* "to_open" target method for 'live' processes.  */
842
 
843
static void
844
record_open_1 (char *name, int from_tty)
845
{
846
  if (record_debug)
847
    fprintf_unfiltered (gdb_stdlog, "Process record: record_open\n");
848
 
849
  /* check exec */
850
  if (!target_has_execution)
851
    error (_("Process record: the program is not being run."));
852
  if (non_stop)
853
    error (_("Process record target can't debug inferior in non-stop mode "
854
             "(non-stop)."));
855
  if (target_async_permitted)
856
    error (_("Process record target can't debug inferior in asynchronous "
857
             "mode (target-async)."));
858
 
859
  if (!gdbarch_process_record_p (target_gdbarch))
860
    error (_("Process record: the current architecture doesn't support "
861
             "record function."));
862
 
863
  if (!tmp_to_resume)
864
    error (_("Could not find 'to_resume' method on the target stack."));
865
  if (!tmp_to_wait)
866
    error (_("Could not find 'to_wait' method on the target stack."));
867
  if (!tmp_to_store_registers)
868
    error (_("Could not find 'to_store_registers' method on the target stack."));
869
  if (!tmp_to_insert_breakpoint)
870
    error (_("Could not find 'to_insert_breakpoint' method on the target stack."));
871
  if (!tmp_to_remove_breakpoint)
872
    error (_("Could not find 'to_remove_breakpoint' method on the target stack."));
873
  if (!tmp_to_stopped_by_watchpoint)
874
    error (_("Could not find 'to_stopped_by_watchpoint' method on the target stack."));
875
  if (!tmp_to_stopped_data_address)
876
    error (_("Could not find 'to_stopped_data_address' method on the target stack."));
877
 
878
  push_target (&record_ops);
879
}
880
 
881
/* "to_open" target method.  Open the process record target.  */
882
 
883
static void
884
record_open (char *name, int from_tty)
885
{
886
  struct target_ops *t;
887
 
888
  if (record_debug)
889
    fprintf_unfiltered (gdb_stdlog, "Process record: record_open\n");
890
 
891
  /* Check if record target is already running.  */
892
  if (current_target.to_stratum == record_stratum)
893
    error (_("Process record target already running.  Use \"record stop\" to "
894
             "stop record target first."));
895
 
896
  /* Reset the tmp beneath pointers.  */
897
  tmp_to_resume_ops = NULL;
898
  tmp_to_resume = NULL;
899
  tmp_to_wait_ops = NULL;
900
  tmp_to_wait = NULL;
901
  tmp_to_store_registers_ops = NULL;
902
  tmp_to_store_registers = NULL;
903
  tmp_to_xfer_partial_ops = NULL;
904
  tmp_to_xfer_partial = NULL;
905
  tmp_to_insert_breakpoint = NULL;
906
  tmp_to_remove_breakpoint = NULL;
907
  tmp_to_stopped_by_watchpoint = NULL;
908
  tmp_to_stopped_data_address = NULL;
909
 
910
  /* Set the beneath function pointers.  */
911
  for (t = current_target.beneath; t != NULL; t = t->beneath)
912
    {
913
      if (!tmp_to_resume)
914
        {
915
          tmp_to_resume = t->to_resume;
916
          tmp_to_resume_ops = t;
917
        }
918
      if (!tmp_to_wait)
919
        {
920
          tmp_to_wait = t->to_wait;
921
          tmp_to_wait_ops = t;
922
        }
923
      if (!tmp_to_store_registers)
924
        {
925
          tmp_to_store_registers = t->to_store_registers;
926
          tmp_to_store_registers_ops = t;
927
        }
928
      if (!tmp_to_xfer_partial)
929
        {
930
          tmp_to_xfer_partial = t->to_xfer_partial;
931
          tmp_to_xfer_partial_ops = t;
932
        }
933
      if (!tmp_to_insert_breakpoint)
934
        tmp_to_insert_breakpoint = t->to_insert_breakpoint;
935
      if (!tmp_to_remove_breakpoint)
936
        tmp_to_remove_breakpoint = t->to_remove_breakpoint;
937
      if (!tmp_to_stopped_by_watchpoint)
938
        tmp_to_stopped_by_watchpoint = t->to_stopped_by_watchpoint;
939
      if (!tmp_to_stopped_data_address)
940
        tmp_to_stopped_data_address = t->to_stopped_data_address;
941
    }
942
  if (!tmp_to_xfer_partial)
943
    error (_("Could not find 'to_xfer_partial' method on the target stack."));
944
 
945
  /* Reset */
946
  record_insn_num = 0;
947
  record_insn_count = 0;
948
  record_list = &record_first;
949
  record_list->next = NULL;
950
 
951
  /* Set the tmp beneath pointers to beneath pointers.  */
952
  record_beneath_to_resume_ops = tmp_to_resume_ops;
953
  record_beneath_to_resume = tmp_to_resume;
954
  record_beneath_to_wait_ops = tmp_to_wait_ops;
955
  record_beneath_to_wait = tmp_to_wait;
956
  record_beneath_to_store_registers_ops = tmp_to_store_registers_ops;
957
  record_beneath_to_store_registers = tmp_to_store_registers;
958
  record_beneath_to_xfer_partial_ops = tmp_to_xfer_partial_ops;
959
  record_beneath_to_xfer_partial = tmp_to_xfer_partial;
960
  record_beneath_to_insert_breakpoint = tmp_to_insert_breakpoint;
961
  record_beneath_to_remove_breakpoint = tmp_to_remove_breakpoint;
962
  record_beneath_to_stopped_by_watchpoint = tmp_to_stopped_by_watchpoint;
963
  record_beneath_to_stopped_data_address = tmp_to_stopped_data_address;
964
 
965
  if (current_target.to_stratum == core_stratum)
966
    record_core_open_1 (name, from_tty);
967
  else
968
    record_open_1 (name, from_tty);
969
}
970
 
971
/* "to_close" target method.  Close the process record target.  */
972
 
973
static void
974
record_close (int quitting)
975
{
976
  struct record_core_buf_entry *entry;
977
 
978
  if (record_debug)
979
    fprintf_unfiltered (gdb_stdlog, "Process record: record_close\n");
980
 
981
  record_list_release (record_list);
982
 
983
  /* Release record_core_regbuf.  */
984
  if (record_core_regbuf)
985
    {
986
      xfree (record_core_regbuf);
987
      record_core_regbuf = NULL;
988
    }
989
 
990
  /* Release record_core_buf_list.  */
991
  if (record_core_buf_list)
992
    {
993
      for (entry = record_core_buf_list->prev; entry; entry = entry->prev)
994
        {
995
          xfree (record_core_buf_list);
996
          record_core_buf_list = entry;
997
        }
998
      record_core_buf_list = NULL;
999
    }
1000
}
1001
 
1002
static int record_resume_step = 0;
1003
 
1004
/* "to_resume" target method.  Resume the process record target.  */
1005
 
1006
static void
1007
record_resume (struct target_ops *ops, ptid_t ptid, int step,
1008
               enum target_signal signal)
1009
{
1010
  record_resume_step = step;
1011
 
1012
  if (!RECORD_IS_REPLAY)
1013
    {
1014
      record_message (get_current_regcache (), signal);
1015
      record_beneath_to_resume (record_beneath_to_resume_ops, ptid, 1,
1016
                                signal);
1017
    }
1018
}
1019
 
1020
static int record_get_sig = 0;
1021
 
1022
/* SIGINT signal handler, registered by "to_wait" method.  */
1023
 
1024
static void
1025
record_sig_handler (int signo)
1026
{
1027
  if (record_debug)
1028
    fprintf_unfiltered (gdb_stdlog, "Process record: get a signal\n");
1029
 
1030
  /* It will break the running inferior in replay mode.  */
1031
  record_resume_step = 1;
1032
 
1033
  /* It will let record_wait set inferior status to get the signal
1034
     SIGINT.  */
1035
  record_get_sig = 1;
1036
}
1037
 
1038
static void
1039
record_wait_cleanups (void *ignore)
1040
{
1041
  if (execution_direction == EXEC_REVERSE)
1042
    {
1043
      if (record_list->next)
1044
        record_list = record_list->next;
1045
    }
1046
  else
1047
    record_list = record_list->prev;
1048
}
1049
 
1050
/* "to_wait" target method for process record target.
1051
 
1052
   In record mode, the target is always run in singlestep mode
1053
   (even when gdb says to continue).  The to_wait method intercepts
1054
   the stop events and determines which ones are to be passed on to
1055
   gdb.  Most stop events are just singlestep events that gdb is not
1056
   to know about, so the to_wait method just records them and keeps
1057
   singlestepping.
1058
 
1059
   In replay mode, this function emulates the recorded execution log,
1060
   one instruction at a time (forward or backward), and determines
1061
   where to stop.  */
1062
 
1063
static ptid_t
1064
record_wait (struct target_ops *ops,
1065
             ptid_t ptid, struct target_waitstatus *status,
1066
             int options)
1067
{
1068
  struct cleanup *set_cleanups = record_gdb_operation_disable_set ();
1069
 
1070
  if (record_debug)
1071
    fprintf_unfiltered (gdb_stdlog,
1072
                        "Process record: record_wait "
1073
                        "record_resume_step = %d\n",
1074
                        record_resume_step);
1075
 
1076
  record_get_sig = 0;
1077
  signal (SIGINT, record_sig_handler);
1078
 
1079
  if (!RECORD_IS_REPLAY && ops != &record_core_ops)
1080
    {
1081
      if (record_resume_step)
1082
        {
1083
          /* This is a single step.  */
1084
          return record_beneath_to_wait (record_beneath_to_wait_ops,
1085
                                         ptid, status, options);
1086
        }
1087
      else
1088
        {
1089
          /* This is not a single step.  */
1090
          ptid_t ret;
1091
          CORE_ADDR tmp_pc;
1092
 
1093
          while (1)
1094
            {
1095
              ret = record_beneath_to_wait (record_beneath_to_wait_ops,
1096
                                            ptid, status, options);
1097
 
1098
              if (record_resume_step)
1099
                return ret;
1100
 
1101
              /* Is this a SIGTRAP?  */
1102
              if (status->kind == TARGET_WAITKIND_STOPPED
1103
                  && status->value.sig == TARGET_SIGNAL_TRAP)
1104
                {
1105
                  struct regcache *regcache;
1106
                  struct address_space *aspace;
1107
 
1108
                  /* Yes -- this is likely our single-step finishing,
1109
                     but check if there's any reason the core would be
1110
                     interested in the event.  */
1111
 
1112
                  registers_changed ();
1113
                  regcache = get_current_regcache ();
1114
                  tmp_pc = regcache_read_pc (regcache);
1115
                  aspace = get_regcache_aspace (regcache);
1116
 
1117
                  if (target_stopped_by_watchpoint ())
1118
                    {
1119
                      /* Always interested in watchpoints.  */
1120
                    }
1121
                  else if (breakpoint_inserted_here_p (aspace, tmp_pc))
1122
                    {
1123
                      /* There is a breakpoint here.  Let the core
1124
                         handle it.  */
1125
                      if (software_breakpoint_inserted_here_p (aspace, tmp_pc))
1126
                        {
1127
                          struct gdbarch *gdbarch = get_regcache_arch (regcache);
1128
                          CORE_ADDR decr_pc_after_break
1129
                            = gdbarch_decr_pc_after_break (gdbarch);
1130
                          if (decr_pc_after_break)
1131
                            regcache_write_pc (regcache,
1132
                                               tmp_pc + decr_pc_after_break);
1133
                        }
1134
                    }
1135
                  else
1136
                    {
1137
                      /* This must be a single-step trap.  Record the
1138
                         insn and issue another step.  */
1139
                      if (!record_message_wrapper_safe (regcache,
1140
                                                        TARGET_SIGNAL_0))
1141
                        {
1142
                           status->kind = TARGET_WAITKIND_STOPPED;
1143
                           status->value.sig = TARGET_SIGNAL_0;
1144
                           break;
1145
                        }
1146
 
1147
                      record_beneath_to_resume (record_beneath_to_resume_ops,
1148
                                                ptid, 1,
1149
                                                TARGET_SIGNAL_0);
1150
                      continue;
1151
                    }
1152
                }
1153
 
1154
              /* The inferior is broken by a breakpoint or a signal.  */
1155
              break;
1156
            }
1157
 
1158
          return ret;
1159
        }
1160
    }
1161
  else
1162
    {
1163
      struct regcache *regcache = get_current_regcache ();
1164
      struct gdbarch *gdbarch = get_regcache_arch (regcache);
1165
      struct address_space *aspace = get_regcache_aspace (regcache);
1166
      int continue_flag = 1;
1167
      int first_record_end = 1;
1168
      struct cleanup *old_cleanups = make_cleanup (record_wait_cleanups, 0);
1169
      CORE_ADDR tmp_pc;
1170
 
1171
      record_hw_watchpoint = 0;
1172
      status->kind = TARGET_WAITKIND_STOPPED;
1173
 
1174
      /* Check breakpoint when forward execute.  */
1175
      if (execution_direction == EXEC_FORWARD)
1176
        {
1177
          tmp_pc = regcache_read_pc (regcache);
1178
          if (breakpoint_inserted_here_p (aspace, tmp_pc))
1179
            {
1180
              int decr_pc_after_break = gdbarch_decr_pc_after_break (gdbarch);
1181
 
1182
              if (record_debug)
1183
                fprintf_unfiltered (gdb_stdlog,
1184
                                    "Process record: break at %s.\n",
1185
                                    paddress (gdbarch, tmp_pc));
1186
 
1187
              if (decr_pc_after_break
1188
                  && !record_resume_step
1189
                  && software_breakpoint_inserted_here_p (aspace, tmp_pc))
1190
                regcache_write_pc (regcache,
1191
                                   tmp_pc + decr_pc_after_break);
1192
              goto replay_out;
1193
            }
1194
        }
1195
 
1196
      /* If GDB is in terminal_inferior mode, it will not get the signal.
1197
         And in GDB replay mode, GDB doesn't need to be in terminal_inferior
1198
         mode, because inferior will not executed.
1199
         Then set it to terminal_ours to make GDB get the signal.  */
1200
      target_terminal_ours ();
1201
 
1202
      /* In EXEC_FORWARD mode, record_list points to the tail of prev
1203
         instruction.  */
1204
      if (execution_direction == EXEC_FORWARD && record_list->next)
1205
        record_list = record_list->next;
1206
 
1207
      /* Loop over the record_list, looking for the next place to
1208
         stop.  */
1209
      do
1210
        {
1211
          /* Check for beginning and end of log.  */
1212
          if (execution_direction == EXEC_REVERSE
1213
              && record_list == &record_first)
1214
            {
1215
              /* Hit beginning of record log in reverse.  */
1216
              status->kind = TARGET_WAITKIND_NO_HISTORY;
1217
              break;
1218
            }
1219
          if (execution_direction != EXEC_REVERSE && !record_list->next)
1220
            {
1221
              /* Hit end of record log going forward.  */
1222
              status->kind = TARGET_WAITKIND_NO_HISTORY;
1223
              break;
1224
            }
1225
 
1226
          record_exec_insn (regcache, gdbarch, record_list);
1227
 
1228
          if (record_list->type == record_end)
1229
            {
1230
              if (record_debug > 1)
1231
                fprintf_unfiltered (gdb_stdlog,
1232
                                    "Process record: record_end %s to "
1233
                                    "inferior.\n",
1234
                                    host_address_to_string (record_list));
1235
 
1236
              if (first_record_end && execution_direction == EXEC_REVERSE)
1237
                {
1238
                  /* When reverse excute, the first record_end is the part of
1239
                     current instruction.  */
1240
                  first_record_end = 0;
1241
                }
1242
              else
1243
                {
1244
                  /* In EXEC_REVERSE mode, this is the record_end of prev
1245
                     instruction.
1246
                     In EXEC_FORWARD mode, this is the record_end of current
1247
                     instruction.  */
1248
                  /* step */
1249
                  if (record_resume_step)
1250
                    {
1251
                      if (record_debug > 1)
1252
                        fprintf_unfiltered (gdb_stdlog,
1253
                                            "Process record: step.\n");
1254
                      continue_flag = 0;
1255
                    }
1256
 
1257
                  /* check breakpoint */
1258
                  tmp_pc = regcache_read_pc (regcache);
1259
                  if (breakpoint_inserted_here_p (aspace, tmp_pc))
1260
                    {
1261
                      int decr_pc_after_break
1262
                        = gdbarch_decr_pc_after_break (gdbarch);
1263
 
1264
                      if (record_debug)
1265
                        fprintf_unfiltered (gdb_stdlog,
1266
                                            "Process record: break "
1267
                                            "at %s.\n",
1268
                                            paddress (gdbarch, tmp_pc));
1269
                      if (decr_pc_after_break
1270
                          && execution_direction == EXEC_FORWARD
1271
                          && !record_resume_step
1272
                          && software_breakpoint_inserted_here_p (aspace,
1273
                                                                  tmp_pc))
1274
                        regcache_write_pc (regcache,
1275
                                           tmp_pc + decr_pc_after_break);
1276
                      continue_flag = 0;
1277
                    }
1278
 
1279
                  if (record_hw_watchpoint)
1280
                    {
1281
                      if (record_debug)
1282
                        fprintf_unfiltered (gdb_stdlog, "\
1283
Process record: hit hw watchpoint.\n");
1284
                      continue_flag = 0;
1285
                    }
1286
                  /* Check target signal */
1287
                  if (record_list->u.end.sigval != TARGET_SIGNAL_0)
1288
                    /* FIXME: better way to check */
1289
                    continue_flag = 0;
1290
                }
1291
            }
1292
 
1293
          if (continue_flag)
1294
            {
1295
              if (execution_direction == EXEC_REVERSE)
1296
                {
1297
                  if (record_list->prev)
1298
                    record_list = record_list->prev;
1299
                }
1300
              else
1301
                {
1302
                  if (record_list->next)
1303
                    record_list = record_list->next;
1304
                }
1305
            }
1306
        }
1307
      while (continue_flag);
1308
 
1309
replay_out:
1310
      if (record_get_sig)
1311
        status->value.sig = TARGET_SIGNAL_INT;
1312
      else if (record_list->u.end.sigval != TARGET_SIGNAL_0)
1313
        /* FIXME: better way to check */
1314
        status->value.sig = record_list->u.end.sigval;
1315
      else
1316
        status->value.sig = TARGET_SIGNAL_TRAP;
1317
 
1318
      discard_cleanups (old_cleanups);
1319
    }
1320
 
1321
  signal (SIGINT, handle_sigint);
1322
 
1323
  do_cleanups (set_cleanups);
1324
  return inferior_ptid;
1325
}
1326
 
1327
static int
1328
record_stopped_by_watchpoint (void)
1329
{
1330
  if (RECORD_IS_REPLAY)
1331
    return record_hw_watchpoint;
1332
  else
1333
    return record_beneath_to_stopped_by_watchpoint ();
1334
}
1335
 
1336
static int
1337
record_stopped_data_address (struct target_ops *ops, CORE_ADDR *addr_p)
1338
{
1339
  if (RECORD_IS_REPLAY)
1340
    return 0;
1341
  else
1342
    return record_beneath_to_stopped_data_address (ops, addr_p);
1343
}
1344
 
1345
/* "to_disconnect" method for process record target.  */
1346
 
1347
static void
1348
record_disconnect (struct target_ops *target, char *args, int from_tty)
1349
{
1350
  if (record_debug)
1351
    fprintf_unfiltered (gdb_stdlog, "Process record: record_disconnect\n");
1352
 
1353
  unpush_target (&record_ops);
1354
  target_disconnect (args, from_tty);
1355
}
1356
 
1357
/* "to_detach" method for process record target.  */
1358
 
1359
static void
1360
record_detach (struct target_ops *ops, char *args, int from_tty)
1361
{
1362
  if (record_debug)
1363
    fprintf_unfiltered (gdb_stdlog, "Process record: record_detach\n");
1364
 
1365
  unpush_target (&record_ops);
1366
  target_detach (args, from_tty);
1367
}
1368
 
1369
/* "to_mourn_inferior" method for process record target.  */
1370
 
1371
static void
1372
record_mourn_inferior (struct target_ops *ops)
1373
{
1374
  if (record_debug)
1375
    fprintf_unfiltered (gdb_stdlog, "Process record: "
1376
                                    "record_mourn_inferior\n");
1377
 
1378
  unpush_target (&record_ops);
1379
  target_mourn_inferior ();
1380
}
1381
 
1382
/* Close process record target before killing the inferior process.  */
1383
 
1384
static void
1385
record_kill (struct target_ops *ops)
1386
{
1387
  if (record_debug)
1388
    fprintf_unfiltered (gdb_stdlog, "Process record: record_kill\n");
1389
 
1390
  unpush_target (&record_ops);
1391
  target_kill ();
1392
}
1393
 
1394
/* Record registers change (by user or by GDB) to list as an instruction.  */
1395
 
1396
static void
1397
record_registers_change (struct regcache *regcache, int regnum)
1398
{
1399
  /* Check record_insn_num.  */
1400
  record_check_insn_num (0);
1401
 
1402
  record_arch_list_head = NULL;
1403
  record_arch_list_tail = NULL;
1404
 
1405
  if (regnum < 0)
1406
    {
1407
      int i;
1408
 
1409
      for (i = 0; i < gdbarch_num_regs (get_regcache_arch (regcache)); i++)
1410
        {
1411
          if (record_arch_list_add_reg (regcache, i))
1412
            {
1413
              record_list_release (record_arch_list_tail);
1414
              error (_("Process record: failed to record execution log."));
1415
            }
1416
        }
1417
    }
1418
  else
1419
    {
1420
      if (record_arch_list_add_reg (regcache, regnum))
1421
        {
1422
          record_list_release (record_arch_list_tail);
1423
          error (_("Process record: failed to record execution log."));
1424
        }
1425
    }
1426
  if (record_arch_list_add_end ())
1427
    {
1428
      record_list_release (record_arch_list_tail);
1429
      error (_("Process record: failed to record execution log."));
1430
    }
1431
  record_list->next = record_arch_list_head;
1432
  record_arch_list_head->prev = record_list;
1433
  record_list = record_arch_list_tail;
1434
 
1435
  if (record_insn_num == record_insn_max_num && record_insn_max_num)
1436
    record_list_release_first ();
1437
  else
1438
    record_insn_num++;
1439
}
1440
 
1441
/* "to_store_registers" method for process record target.  */
1442
 
1443
static void
1444
record_store_registers (struct target_ops *ops, struct regcache *regcache,
1445
                        int regno)
1446
{
1447
  if (!record_gdb_operation_disable)
1448
    {
1449
      if (RECORD_IS_REPLAY)
1450
        {
1451
          int n;
1452
 
1453
          /* Let user choose if he wants to write register or not.  */
1454
          if (regno < 0)
1455
            n =
1456
              query (_("Because GDB is in replay mode, changing the "
1457
                       "value of a register will make the execution "
1458
                       "log unusable from this point onward.  "
1459
                       "Change all registers?"));
1460
          else
1461
            n =
1462
              query (_("Because GDB is in replay mode, changing the value "
1463
                       "of a register will make the execution log unusable "
1464
                       "from this point onward.  Change register %s?"),
1465
                      gdbarch_register_name (get_regcache_arch (regcache),
1466
                                               regno));
1467
 
1468
          if (!n)
1469
            {
1470
              /* Invalidate the value of regcache that was set in function
1471
                 "regcache_raw_write".  */
1472
              if (regno < 0)
1473
                {
1474
                  int i;
1475
 
1476
                  for (i = 0;
1477
                       i < gdbarch_num_regs (get_regcache_arch (regcache));
1478
                       i++)
1479
                    regcache_invalidate (regcache, i);
1480
                }
1481
              else
1482
                regcache_invalidate (regcache, regno);
1483
 
1484
              error (_("Process record canceled the operation."));
1485
            }
1486
 
1487
          /* Destroy the record from here forward.  */
1488
          record_list_release_following (record_list);
1489
        }
1490
 
1491
      record_registers_change (regcache, regno);
1492
    }
1493
  record_beneath_to_store_registers (record_beneath_to_store_registers_ops,
1494
                                     regcache, regno);
1495
}
1496
 
1497
/* "to_xfer_partial" method.  Behavior is conditional on RECORD_IS_REPLAY.
1498
   In replay mode, we cannot write memory unles we are willing to
1499
   invalidate the record/replay log from this point forward.  */
1500
 
1501
static LONGEST
1502
record_xfer_partial (struct target_ops *ops, enum target_object object,
1503
                     const char *annex, gdb_byte *readbuf,
1504
                     const gdb_byte *writebuf, ULONGEST offset, LONGEST len)
1505
{
1506
  if (!record_gdb_operation_disable
1507
      && (object == TARGET_OBJECT_MEMORY
1508
          || object == TARGET_OBJECT_RAW_MEMORY) && writebuf)
1509
    {
1510
      if (RECORD_IS_REPLAY)
1511
        {
1512
          /* Let user choose if he wants to write memory or not.  */
1513
          if (!query (_("Because GDB is in replay mode, writing to memory "
1514
                        "will make the execution log unusable from this "
1515
                        "point onward.  Write memory at address %s?"),
1516
                       paddress (target_gdbarch, offset)))
1517
            error (_("Process record canceled the operation."));
1518
 
1519
          /* Destroy the record from here forward.  */
1520
          record_list_release_following (record_list);
1521
        }
1522
 
1523
      /* Check record_insn_num */
1524
      record_check_insn_num (0);
1525
 
1526
      /* Record registers change to list as an instruction.  */
1527
      record_arch_list_head = NULL;
1528
      record_arch_list_tail = NULL;
1529
      if (record_arch_list_add_mem (offset, len))
1530
        {
1531
          record_list_release (record_arch_list_tail);
1532
          if (record_debug)
1533
            fprintf_unfiltered (gdb_stdlog,
1534
                                "Process record: failed to record "
1535
                                "execution log.");
1536
          return -1;
1537
        }
1538
      if (record_arch_list_add_end ())
1539
        {
1540
          record_list_release (record_arch_list_tail);
1541
          if (record_debug)
1542
            fprintf_unfiltered (gdb_stdlog,
1543
                                "Process record: failed to record "
1544
                                "execution log.");
1545
          return -1;
1546
        }
1547
      record_list->next = record_arch_list_head;
1548
      record_arch_list_head->prev = record_list;
1549
      record_list = record_arch_list_tail;
1550
 
1551
      if (record_insn_num == record_insn_max_num && record_insn_max_num)
1552
        record_list_release_first ();
1553
      else
1554
        record_insn_num++;
1555
    }
1556
 
1557
  return record_beneath_to_xfer_partial (record_beneath_to_xfer_partial_ops,
1558
                                         object, annex, readbuf, writebuf,
1559
                                         offset, len);
1560
}
1561
 
1562
/* Behavior is conditional on RECORD_IS_REPLAY.
1563
   We will not actually insert or remove breakpoints when replaying,
1564
   nor when recording.  */
1565
 
1566
static int
1567
record_insert_breakpoint (struct gdbarch *gdbarch,
1568
                          struct bp_target_info *bp_tgt)
1569
{
1570
  if (!RECORD_IS_REPLAY)
1571
    {
1572
      struct cleanup *old_cleanups = record_gdb_operation_disable_set ();
1573
      int ret = record_beneath_to_insert_breakpoint (gdbarch, bp_tgt);
1574
 
1575
      do_cleanups (old_cleanups);
1576
 
1577
      return ret;
1578
    }
1579
 
1580
  return 0;
1581
}
1582
 
1583
/* "to_remove_breakpoint" method for process record target.  */
1584
 
1585
static int
1586
record_remove_breakpoint (struct gdbarch *gdbarch,
1587
                          struct bp_target_info *bp_tgt)
1588
{
1589
  if (!RECORD_IS_REPLAY)
1590
    {
1591
      struct cleanup *old_cleanups = record_gdb_operation_disable_set ();
1592
      int ret = record_beneath_to_remove_breakpoint (gdbarch, bp_tgt);
1593
 
1594
      do_cleanups (old_cleanups);
1595
 
1596
      return ret;
1597
    }
1598
 
1599
  return 0;
1600
}
1601
 
1602
/* "to_can_execute_reverse" method for process record target.  */
1603
 
1604
static int
1605
record_can_execute_reverse (void)
1606
{
1607
  return 1;
1608
}
1609
 
1610
/* "to_get_bookmark" method for process record and prec over core.  */
1611
 
1612
static gdb_byte *
1613
record_get_bookmark (char *args, int from_tty)
1614
{
1615
  gdb_byte *ret = NULL;
1616
 
1617
  /* Return stringified form of instruction count.  */
1618
  if (record_list && record_list->type == record_end)
1619
    ret = xstrdup (pulongest (record_list->u.end.insn_num));
1620
 
1621
  if (record_debug)
1622
    {
1623
      if (ret)
1624
        fprintf_unfiltered (gdb_stdlog,
1625
                            "record_get_bookmark returns %s\n", ret);
1626
      else
1627
        fprintf_unfiltered (gdb_stdlog,
1628
                            "record_get_bookmark returns NULL\n");
1629
    }
1630
  return ret;
1631
}
1632
 
1633
/* The implementation of the command "record goto".  */
1634
static void cmd_record_goto (char *, int);
1635
 
1636
/* "to_goto_bookmark" method for process record and prec over core.  */
1637
 
1638
static void
1639
record_goto_bookmark (gdb_byte *bookmark, int from_tty)
1640
{
1641
  if (record_debug)
1642
    fprintf_unfiltered (gdb_stdlog,
1643
                        "record_goto_bookmark receives %s\n", bookmark);
1644
 
1645
  if (bookmark[0] == '\'' || bookmark[0] == '\"')
1646
    {
1647
      if (bookmark[strlen (bookmark) - 1] != bookmark[0])
1648
        error (_("Unbalanced quotes: %s"), bookmark);
1649
 
1650
      /* Strip trailing quote.  */
1651
      bookmark[strlen (bookmark) - 1] = '\0';
1652
      /* Strip leading quote.  */
1653
      bookmark++;
1654
      /* Pass along to cmd_record_goto.  */
1655
    }
1656
 
1657
  cmd_record_goto ((char *) bookmark, from_tty);
1658
  return;
1659
}
1660
 
1661
static void
1662
init_record_ops (void)
1663
{
1664
  record_ops.to_shortname = "record";
1665
  record_ops.to_longname = "Process record and replay target";
1666
  record_ops.to_doc =
1667
    "Log program while executing and replay execution from log.";
1668
  record_ops.to_open = record_open;
1669
  record_ops.to_close = record_close;
1670
  record_ops.to_resume = record_resume;
1671
  record_ops.to_wait = record_wait;
1672
  record_ops.to_disconnect = record_disconnect;
1673
  record_ops.to_detach = record_detach;
1674
  record_ops.to_mourn_inferior = record_mourn_inferior;
1675
  record_ops.to_kill = record_kill;
1676
  record_ops.to_create_inferior = find_default_create_inferior;
1677
  record_ops.to_store_registers = record_store_registers;
1678
  record_ops.to_xfer_partial = record_xfer_partial;
1679
  record_ops.to_insert_breakpoint = record_insert_breakpoint;
1680
  record_ops.to_remove_breakpoint = record_remove_breakpoint;
1681
  record_ops.to_stopped_by_watchpoint = record_stopped_by_watchpoint;
1682
  record_ops.to_stopped_data_address = record_stopped_data_address;
1683
  record_ops.to_can_execute_reverse = record_can_execute_reverse;
1684
  record_ops.to_stratum = record_stratum;
1685
  /* Add bookmark target methods.  */
1686
  record_ops.to_get_bookmark = record_get_bookmark;
1687
  record_ops.to_goto_bookmark = record_goto_bookmark;
1688
  record_ops.to_magic = OPS_MAGIC;
1689
}
1690
 
1691
/* "to_resume" method for prec over corefile.  */
1692
 
1693
static void
1694
record_core_resume (struct target_ops *ops, ptid_t ptid, int step,
1695
                    enum target_signal signal)
1696
{
1697
  record_resume_step = step;
1698
}
1699
 
1700
/* "to_kill" method for prec over corefile.  */
1701
 
1702
static void
1703
record_core_kill (struct target_ops *ops)
1704
{
1705
  if (record_debug)
1706
    fprintf_unfiltered (gdb_stdlog, "Process record: record_core_kill\n");
1707
 
1708
  unpush_target (&record_core_ops);
1709
}
1710
 
1711
/* "to_fetch_registers" method for prec over corefile.  */
1712
 
1713
static void
1714
record_core_fetch_registers (struct target_ops *ops,
1715
                             struct regcache *regcache,
1716
                             int regno)
1717
{
1718
  if (regno < 0)
1719
    {
1720
      int num = gdbarch_num_regs (get_regcache_arch (regcache));
1721
      int i;
1722
 
1723
      for (i = 0; i < num; i ++)
1724
        regcache_raw_supply (regcache, i,
1725
                             record_core_regbuf + MAX_REGISTER_SIZE * i);
1726
    }
1727
  else
1728
    regcache_raw_supply (regcache, regno,
1729
                         record_core_regbuf + MAX_REGISTER_SIZE * regno);
1730
}
1731
 
1732
/* "to_prepare_to_store" method for prec over corefile.  */
1733
 
1734
static void
1735
record_core_prepare_to_store (struct regcache *regcache)
1736
{
1737
}
1738
 
1739
/* "to_store_registers" method for prec over corefile.  */
1740
 
1741
static void
1742
record_core_store_registers (struct target_ops *ops,
1743
                             struct regcache *regcache,
1744
                             int regno)
1745
{
1746
  if (record_gdb_operation_disable)
1747
    regcache_raw_collect (regcache, regno,
1748
                          record_core_regbuf + MAX_REGISTER_SIZE * regno);
1749
  else
1750
    error (_("You can't do that without a process to debug."));
1751
}
1752
 
1753
/* "to_xfer_partial" method for prec over corefile.  */
1754
 
1755
static LONGEST
1756
record_core_xfer_partial (struct target_ops *ops, enum target_object object,
1757
                          const char *annex, gdb_byte *readbuf,
1758
                          const gdb_byte *writebuf, ULONGEST offset,
1759
                          LONGEST len)
1760
{
1761
  if (object == TARGET_OBJECT_MEMORY)
1762
    {
1763
      if (record_gdb_operation_disable || !writebuf)
1764
        {
1765
          struct target_section *p;
1766
 
1767
          for (p = record_core_start; p < record_core_end; p++)
1768
            {
1769
              if (offset >= p->addr)
1770
                {
1771
                  struct record_core_buf_entry *entry;
1772
                  ULONGEST sec_offset;
1773
 
1774
                  if (offset >= p->endaddr)
1775
                    continue;
1776
 
1777
                  if (offset + len > p->endaddr)
1778
                    len = p->endaddr - offset;
1779
 
1780
                  sec_offset = offset - p->addr;
1781
 
1782
                  /* Read readbuf or write writebuf p, offset, len.  */
1783
                  /* Check flags.  */
1784
                  if (p->the_bfd_section->flags & SEC_CONSTRUCTOR
1785
                      || (p->the_bfd_section->flags & SEC_HAS_CONTENTS) == 0)
1786
                    {
1787
                      if (readbuf)
1788
                        memset (readbuf, 0, len);
1789
                      return len;
1790
                    }
1791
                  /* Get record_core_buf_entry.  */
1792
                  for (entry = record_core_buf_list; entry;
1793
                       entry = entry->prev)
1794
                    if (entry->p == p)
1795
                      break;
1796
                  if (writebuf)
1797
                    {
1798
                      if (!entry)
1799
                        {
1800
                          /* Add a new entry.  */
1801
                          entry = (struct record_core_buf_entry *)
1802
                            xmalloc (sizeof (struct record_core_buf_entry));
1803
                          entry->p = p;
1804
                          if (!bfd_malloc_and_get_section (p->bfd,
1805
                                                           p->the_bfd_section,
1806
                                                           &entry->buf))
1807
                            {
1808
                              xfree (entry);
1809
                              return 0;
1810
                            }
1811
                          entry->prev = record_core_buf_list;
1812
                          record_core_buf_list = entry;
1813
                        }
1814
 
1815
                      memcpy (entry->buf + sec_offset, writebuf,
1816
                              (size_t) len);
1817
                    }
1818
                  else
1819
                    {
1820
                      if (!entry)
1821
                        return record_beneath_to_xfer_partial
1822
                          (record_beneath_to_xfer_partial_ops,
1823
                           object, annex, readbuf, writebuf,
1824
                           offset, len);
1825
 
1826
                      memcpy (readbuf, entry->buf + sec_offset,
1827
                              (size_t) len);
1828
                    }
1829
 
1830
                  return len;
1831
                }
1832
            }
1833
 
1834
          return -1;
1835
        }
1836
      else
1837
        error (_("You can't do that without a process to debug."));
1838
    }
1839
 
1840
  return record_beneath_to_xfer_partial (record_beneath_to_xfer_partial_ops,
1841
                                         object, annex, readbuf, writebuf,
1842
                                         offset, len);
1843
}
1844
 
1845
/* "to_insert_breakpoint" method for prec over corefile.  */
1846
 
1847
static int
1848
record_core_insert_breakpoint (struct gdbarch *gdbarch,
1849
                               struct bp_target_info *bp_tgt)
1850
{
1851
  return 0;
1852
}
1853
 
1854
/* "to_remove_breakpoint" method for prec over corefile.  */
1855
 
1856
static int
1857
record_core_remove_breakpoint (struct gdbarch *gdbarch,
1858
                               struct bp_target_info *bp_tgt)
1859
{
1860
  return 0;
1861
}
1862
 
1863
/* "to_has_execution" method for prec over corefile.  */
1864
 
1865
int
1866
record_core_has_execution (struct target_ops *ops)
1867
{
1868
  return 1;
1869
}
1870
 
1871
static void
1872
init_record_core_ops (void)
1873
{
1874
  record_core_ops.to_shortname = "record-core";
1875
  record_core_ops.to_longname = "Process record and replay target";
1876
  record_core_ops.to_doc =
1877
    "Log program while executing and replay execution from log.";
1878
  record_core_ops.to_open = record_open;
1879
  record_core_ops.to_close = record_close;
1880
  record_core_ops.to_resume = record_core_resume;
1881
  record_core_ops.to_wait = record_wait;
1882
  record_core_ops.to_kill = record_core_kill;
1883
  record_core_ops.to_fetch_registers = record_core_fetch_registers;
1884
  record_core_ops.to_prepare_to_store = record_core_prepare_to_store;
1885
  record_core_ops.to_store_registers = record_core_store_registers;
1886
  record_core_ops.to_xfer_partial = record_core_xfer_partial;
1887
  record_core_ops.to_insert_breakpoint = record_core_insert_breakpoint;
1888
  record_core_ops.to_remove_breakpoint = record_core_remove_breakpoint;
1889
  record_core_ops.to_stopped_by_watchpoint = record_stopped_by_watchpoint;
1890
  record_core_ops.to_stopped_data_address = record_stopped_data_address;
1891
  record_core_ops.to_can_execute_reverse = record_can_execute_reverse;
1892
  record_core_ops.to_has_execution = record_core_has_execution;
1893
  record_core_ops.to_stratum = record_stratum;
1894
  /* Add bookmark target methods.  */
1895
  record_core_ops.to_get_bookmark = record_get_bookmark;
1896
  record_core_ops.to_goto_bookmark = record_goto_bookmark;
1897
  record_core_ops.to_magic = OPS_MAGIC;
1898
}
1899
 
1900
/* Implement "show record debug" command.  */
1901
 
1902
static void
1903
show_record_debug (struct ui_file *file, int from_tty,
1904
                   struct cmd_list_element *c, const char *value)
1905
{
1906
  fprintf_filtered (file, _("Debugging of process record target is %s.\n"),
1907
                    value);
1908
}
1909
 
1910
/* Alias for "target record".  */
1911
 
1912
static void
1913
cmd_record_start (char *args, int from_tty)
1914
{
1915
  execute_command ("target record", from_tty);
1916
}
1917
 
1918
/* Truncate the record log from the present point
1919
   of replay until the end.  */
1920
 
1921
static void
1922
cmd_record_delete (char *args, int from_tty)
1923
{
1924
  if (current_target.to_stratum == record_stratum)
1925
    {
1926
      if (RECORD_IS_REPLAY)
1927
        {
1928
          if (!from_tty || query (_("Delete the log from this point forward "
1929
                                    "and begin to record the running message "
1930
                                    "at current PC?")))
1931
            record_list_release_following (record_list);
1932
        }
1933
      else
1934
          printf_unfiltered (_("Already at end of record list.\n"));
1935
 
1936
    }
1937
  else
1938
    printf_unfiltered (_("Process record is not started.\n"));
1939
}
1940
 
1941
/* Implement the "stoprecord" or "record stop" command.  */
1942
 
1943
static void
1944
cmd_record_stop (char *args, int from_tty)
1945
{
1946
  if (current_target.to_stratum == record_stratum)
1947
    {
1948
      unpush_target (&record_ops);
1949
      printf_unfiltered (_("Process record is stopped and all execution "
1950
                           "logs are deleted.\n"));
1951
    }
1952
  else
1953
    printf_unfiltered (_("Process record is not started.\n"));
1954
}
1955
 
1956
/* Set upper limit of record log size.  */
1957
 
1958
static void
1959
set_record_insn_max_num (char *args, int from_tty, struct cmd_list_element *c)
1960
{
1961
  if (record_insn_num > record_insn_max_num && record_insn_max_num)
1962
    {
1963
      /* Count down record_insn_num while releasing records from list.  */
1964
      while (record_insn_num > record_insn_max_num)
1965
        {
1966
          record_list_release_first ();
1967
          record_insn_num--;
1968
        }
1969
    }
1970
}
1971
 
1972
static struct cmd_list_element *record_cmdlist, *set_record_cmdlist,
1973
                               *show_record_cmdlist, *info_record_cmdlist;
1974
 
1975
static void
1976
set_record_command (char *args, int from_tty)
1977
{
1978
  printf_unfiltered (_("\
1979
\"set record\" must be followed by an apporpriate subcommand.\n"));
1980
  help_list (set_record_cmdlist, "set record ", all_commands, gdb_stdout);
1981
}
1982
 
1983
static void
1984
show_record_command (char *args, int from_tty)
1985
{
1986
  cmd_show_list (show_record_cmdlist, from_tty, "");
1987
}
1988
 
1989
/* Display some statistics about the execution log.  */
1990
 
1991
static void
1992
info_record_command (char *args, int from_tty)
1993
{
1994
  struct record_entry *p;
1995
 
1996
  if (current_target.to_stratum == record_stratum)
1997
    {
1998
      if (RECORD_IS_REPLAY)
1999
        printf_filtered (_("Replay mode:\n"));
2000
      else
2001
        printf_filtered (_("Record mode:\n"));
2002
 
2003
      /* Find entry for first actual instruction in the log.  */
2004
      for (p = record_first.next;
2005
           p != NULL && p->type != record_end;
2006
           p = p->next)
2007
        ;
2008
 
2009
      /* Do we have a log at all?  */
2010
      if (p != NULL && p->type == record_end)
2011
        {
2012
          /* Display instruction number for first instruction in the log.  */
2013
          printf_filtered (_("Lowest recorded instruction number is %s.\n"),
2014
                           pulongest (p->u.end.insn_num));
2015
 
2016
          /* If in replay mode, display where we are in the log.  */
2017
          if (RECORD_IS_REPLAY)
2018
            printf_filtered (_("Current instruction number is %s.\n"),
2019
                             pulongest (record_list->u.end.insn_num));
2020
 
2021
          /* Display instruction number for last instruction in the log.  */
2022
          printf_filtered (_("Highest recorded instruction number is %s.\n"),
2023
                           pulongest (record_insn_count));
2024
 
2025
          /* Display log count.  */
2026
          printf_filtered (_("Log contains %d instructions.\n"),
2027
                           record_insn_num);
2028
        }
2029
      else
2030
        {
2031
          printf_filtered (_("No instructions have been logged.\n"));
2032
        }
2033
    }
2034
  else
2035
    {
2036
      printf_filtered (_("target record is not active.\n"));
2037
    }
2038
 
2039
  /* Display max log size.  */
2040
  printf_filtered (_("Max logged instructions is %d.\n"),
2041
                   record_insn_max_num);
2042
}
2043
 
2044
/* Record log save-file format
2045
   Version 1 (never released)
2046
 
2047
   Header:
2048
     4 bytes: magic number htonl(0x20090829).
2049
       NOTE: be sure to change whenever this file format changes!
2050
 
2051
   Records:
2052
     record_end:
2053
       1 byte:  record type (record_end, see enum record_type).
2054
     record_reg:
2055
       1 byte:  record type (record_reg, see enum record_type).
2056
       8 bytes: register id (network byte order).
2057
       MAX_REGISTER_SIZE bytes: register value.
2058
     record_mem:
2059
       1 byte:  record type (record_mem, see enum record_type).
2060
       8 bytes: memory length (network byte order).
2061
       8 bytes: memory address (network byte order).
2062
       n bytes: memory value (n == memory length).
2063
 
2064
   Version 2
2065
     4 bytes: magic number netorder32(0x20091016).
2066
       NOTE: be sure to change whenever this file format changes!
2067
 
2068
   Records:
2069
     record_end:
2070
       1 byte:  record type (record_end, see enum record_type).
2071
       4 bytes: signal
2072
       4 bytes: instruction count
2073
     record_reg:
2074
       1 byte:  record type (record_reg, see enum record_type).
2075
       4 bytes: register id (network byte order).
2076
       n bytes: register value (n == actual register size).
2077
                (eg. 4 bytes for x86 general registers).
2078
     record_mem:
2079
       1 byte:  record type (record_mem, see enum record_type).
2080
       4 bytes: memory length (network byte order).
2081
       8 bytes: memory address (network byte order).
2082
       n bytes: memory value (n == memory length).
2083
 
2084
*/
2085
 
2086
/* bfdcore_read -- read bytes from a core file section.  */
2087
 
2088
static inline void
2089
bfdcore_read (bfd *obfd, asection *osec, void *buf, int len, int *offset)
2090
{
2091
  int ret = bfd_get_section_contents (obfd, osec, buf, *offset, len);
2092
 
2093
  if (ret)
2094
    *offset += len;
2095
  else
2096
    error (_("Failed to read %d bytes from core file %s ('%s').\n"),
2097
           len, bfd_get_filename (obfd),
2098
           bfd_errmsg (bfd_get_error ()));
2099
}
2100
 
2101
static inline uint64_t
2102
netorder64 (uint64_t input)
2103
{
2104
  uint64_t ret;
2105
 
2106
  store_unsigned_integer ((gdb_byte *) &ret, sizeof (ret),
2107
                          BFD_ENDIAN_BIG, input);
2108
  return ret;
2109
}
2110
 
2111
static inline uint32_t
2112
netorder32 (uint32_t input)
2113
{
2114
  uint32_t ret;
2115
 
2116
  store_unsigned_integer ((gdb_byte *) &ret, sizeof (ret),
2117
                          BFD_ENDIAN_BIG, input);
2118
  return ret;
2119
}
2120
 
2121
static inline uint16_t
2122
netorder16 (uint16_t input)
2123
{
2124
  uint16_t ret;
2125
 
2126
  store_unsigned_integer ((gdb_byte *) &ret, sizeof (ret),
2127
                          BFD_ENDIAN_BIG, input);
2128
  return ret;
2129
}
2130
 
2131
/* Restore the execution log from a core_bfd file.  */
2132
static void
2133
record_restore (void)
2134
{
2135
  uint32_t magic;
2136
  struct cleanup *old_cleanups;
2137
  struct record_entry *rec;
2138
  asection *osec;
2139
  uint32_t osec_size;
2140
  int bfd_offset = 0;
2141
  struct regcache *regcache;
2142
 
2143
  /* We restore the execution log from the open core bfd,
2144
     if there is one.  */
2145
  if (core_bfd == NULL)
2146
    return;
2147
 
2148
  /* "record_restore" can only be called when record list is empty.  */
2149
  gdb_assert (record_first.next == NULL);
2150
 
2151
  if (record_debug)
2152
    fprintf_unfiltered (gdb_stdlog, "Restoring recording from core file.\n");
2153
 
2154
  /* Now need to find our special note section.  */
2155
  osec = bfd_get_section_by_name (core_bfd, "null0");
2156
  osec_size = bfd_section_size (core_bfd, osec);
2157
  if (record_debug)
2158
    fprintf_unfiltered (gdb_stdlog, "Find precord section %s.\n",
2159
                        osec ? "succeeded" : "failed");
2160
  if (osec == NULL)
2161
    return;
2162
  if (record_debug)
2163
    fprintf_unfiltered (gdb_stdlog, "%s", bfd_section_name (core_bfd, osec));
2164
 
2165
  /* Check the magic code.  */
2166
  bfdcore_read (core_bfd, osec, &magic, sizeof (magic), &bfd_offset);
2167
  if (magic != RECORD_FILE_MAGIC)
2168
    error (_("Version mis-match or file format error in core file %s."),
2169
           bfd_get_filename (core_bfd));
2170
  if (record_debug)
2171
    fprintf_unfiltered (gdb_stdlog, "\
2172
  Reading 4-byte magic cookie RECORD_FILE_MAGIC (0x%s)\n",
2173
                        phex_nz (netorder32 (magic), 4));
2174
 
2175
  /* Restore the entries in recfd into record_arch_list_head and
2176
     record_arch_list_tail.  */
2177
  record_arch_list_head = NULL;
2178
  record_arch_list_tail = NULL;
2179
  record_insn_num = 0;
2180
  old_cleanups = make_cleanup (record_arch_list_cleanups, 0);
2181
  regcache = get_current_regcache ();
2182
 
2183
  while (1)
2184
    {
2185
      uint8_t rectype;
2186
      uint32_t regnum, len, signal, count;
2187
      uint64_t addr;
2188
 
2189
      /* We are finished when offset reaches osec_size.  */
2190
      if (bfd_offset >= osec_size)
2191
        break;
2192
      bfdcore_read (core_bfd, osec, &rectype, sizeof (rectype), &bfd_offset);
2193
 
2194
      switch (rectype)
2195
        {
2196
        case record_reg: /* reg */
2197
          /* Get register number to regnum.  */
2198
          bfdcore_read (core_bfd, osec, &regnum,
2199
                        sizeof (regnum), &bfd_offset);
2200
          regnum = netorder32 (regnum);
2201
 
2202
          rec = record_reg_alloc (regcache, regnum);
2203
 
2204
          /* Get val.  */
2205
          bfdcore_read (core_bfd, osec, record_get_loc (rec),
2206
                        rec->u.reg.len, &bfd_offset);
2207
 
2208
          if (record_debug)
2209
            fprintf_unfiltered (gdb_stdlog, "\
2210
  Reading register %d (1 plus %lu plus %d bytes)\n",
2211
                                rec->u.reg.num,
2212
                                (unsigned long) sizeof (regnum),
2213
                                rec->u.reg.len);
2214
          break;
2215
 
2216
        case record_mem: /* mem */
2217
          /* Get len.  */
2218
          bfdcore_read (core_bfd, osec, &len,
2219
                        sizeof (len), &bfd_offset);
2220
          len = netorder32 (len);
2221
 
2222
          /* Get addr.  */
2223
          bfdcore_read (core_bfd, osec, &addr,
2224
                        sizeof (addr), &bfd_offset);
2225
          addr = netorder64 (addr);
2226
 
2227
          rec = record_mem_alloc (addr, len);
2228
 
2229
          /* Get val.  */
2230
          bfdcore_read (core_bfd, osec, record_get_loc (rec),
2231
                        rec->u.mem.len, &bfd_offset);
2232
 
2233
          if (record_debug)
2234
            fprintf_unfiltered (gdb_stdlog, "\
2235
  Reading memory %s (1 plus %lu plus %lu plus %d bytes)\n",
2236
                                paddress (get_current_arch (),
2237
                                          rec->u.mem.addr),
2238
                                (unsigned long) sizeof (addr),
2239
                                (unsigned long) sizeof (len),
2240
                                rec->u.mem.len);
2241
          break;
2242
 
2243
        case record_end: /* end */
2244
          rec = record_end_alloc ();
2245
          record_insn_num ++;
2246
 
2247
          /* Get signal value.  */
2248
          bfdcore_read (core_bfd, osec, &signal,
2249
                        sizeof (signal), &bfd_offset);
2250
          signal = netorder32 (signal);
2251
          rec->u.end.sigval = signal;
2252
 
2253
          /* Get insn count.  */
2254
          bfdcore_read (core_bfd, osec, &count,
2255
                        sizeof (count), &bfd_offset);
2256
          count = netorder32 (count);
2257
          rec->u.end.insn_num = count;
2258
          record_insn_count = count + 1;
2259
          if (record_debug)
2260
            fprintf_unfiltered (gdb_stdlog, "\
2261
  Reading record_end (1 + %lu + %lu bytes), offset == %s\n",
2262
                                (unsigned long) sizeof (signal),
2263
                                (unsigned long) sizeof (count),
2264
                                paddress (get_current_arch (),
2265
                                          bfd_offset));
2266
          break;
2267
 
2268
        default:
2269
          error (_("Bad entry type in core file %s."),
2270
                 bfd_get_filename (core_bfd));
2271
          break;
2272
        }
2273
 
2274
      /* Add rec to record arch list.  */
2275
      record_arch_list_add (rec);
2276
    }
2277
 
2278
  discard_cleanups (old_cleanups);
2279
 
2280
  /* Add record_arch_list_head to the end of record list.  */
2281
  record_first.next = record_arch_list_head;
2282
  record_arch_list_head->prev = &record_first;
2283
  record_arch_list_tail->next = NULL;
2284
  record_list = &record_first;
2285
 
2286
  /* Update record_insn_max_num.  */
2287
  if (record_insn_num > record_insn_max_num)
2288
    {
2289
      record_insn_max_num = record_insn_num;
2290
      warning (_("Auto increase record/replay buffer limit to %d."),
2291
               record_insn_max_num);
2292
    }
2293
 
2294
  /* Succeeded.  */
2295
  printf_filtered (_("Restored records from core file %s.\n"),
2296
                   bfd_get_filename (core_bfd));
2297
 
2298
  print_stack_frame (get_selected_frame (NULL), 1, SRC_AND_LOC);
2299
}
2300
 
2301
/* bfdcore_write -- write bytes into a core file section.  */
2302
 
2303
static inline void
2304
bfdcore_write (bfd *obfd, asection *osec, void *buf, int len, int *offset)
2305
{
2306
  int ret = bfd_set_section_contents (obfd, osec, buf, *offset, len);
2307
 
2308
  if (ret)
2309
    *offset += len;
2310
  else
2311
    error (_("Failed to write %d bytes to core file %s ('%s').\n"),
2312
           len, bfd_get_filename (obfd),
2313
           bfd_errmsg (bfd_get_error ()));
2314
}
2315
 
2316
/* Restore the execution log from a file.  We use a modified elf
2317
   corefile format, with an extra section for our data.  */
2318
 
2319
static void
2320
cmd_record_restore (char *args, int from_tty)
2321
{
2322
  core_file_command (args, from_tty);
2323
  record_open (args, from_tty);
2324
}
2325
 
2326
static void
2327
record_save_cleanups (void *data)
2328
{
2329
  bfd *obfd = data;
2330
  char *pathname = xstrdup (bfd_get_filename (obfd));
2331
 
2332
  bfd_close (obfd);
2333
  unlink (pathname);
2334
  xfree (pathname);
2335
}
2336
 
2337
/* Save the execution log to a file.  We use a modified elf corefile
2338
   format, with an extra section for our data.  */
2339
 
2340
static void
2341
cmd_record_save (char *args, int from_tty)
2342
{
2343
  char *recfilename, recfilename_buffer[40];
2344
  struct record_entry *cur_record_list;
2345
  uint32_t magic;
2346
  struct regcache *regcache;
2347
  struct gdbarch *gdbarch;
2348
  struct cleanup *old_cleanups;
2349
  struct cleanup *set_cleanups;
2350
  bfd *obfd;
2351
  int save_size = 0;
2352
  asection *osec = NULL;
2353
  int bfd_offset = 0;
2354
 
2355
  if (strcmp (current_target.to_shortname, "record") != 0)
2356
    error (_("This command can only be used with target 'record'.\n"
2357
             "Use 'target record' first.\n"));
2358
 
2359
  if (args && *args)
2360
    recfilename = args;
2361
  else
2362
    {
2363
      /* Default recfile name is "gdb_record.PID".  */
2364
      snprintf (recfilename_buffer, sizeof (recfilename_buffer),
2365
                "gdb_record.%d", PIDGET (inferior_ptid));
2366
      recfilename = recfilename_buffer;
2367
    }
2368
 
2369
  /* Open the save file.  */
2370
  if (record_debug)
2371
    fprintf_unfiltered (gdb_stdlog, "Saving execution log to core file '%s'\n",
2372
                        recfilename);
2373
 
2374
  /* Open the output file.  */
2375
  obfd = create_gcore_bfd (recfilename);
2376
  old_cleanups = make_cleanup (record_save_cleanups, obfd);
2377
 
2378
  /* Save the current record entry to "cur_record_list".  */
2379
  cur_record_list = record_list;
2380
 
2381
  /* Get the values of regcache and gdbarch.  */
2382
  regcache = get_current_regcache ();
2383
  gdbarch = get_regcache_arch (regcache);
2384
 
2385
  /* Disable the GDB operation record.  */
2386
  set_cleanups = record_gdb_operation_disable_set ();
2387
 
2388
  /* Reverse execute to the begin of record list.  */
2389
  while (1)
2390
    {
2391
      /* Check for beginning and end of log.  */
2392
      if (record_list == &record_first)
2393
        break;
2394
 
2395
      record_exec_insn (regcache, gdbarch, record_list);
2396
 
2397
      if (record_list->prev)
2398
        record_list = record_list->prev;
2399
    }
2400
 
2401
  /* Compute the size needed for the extra bfd section.  */
2402
  save_size = 4;        /* magic cookie */
2403
  for (record_list = record_first.next; record_list;
2404
       record_list = record_list->next)
2405
    switch (record_list->type)
2406
      {
2407
      case record_end:
2408
        save_size += 1 + 4 + 4;
2409
        break;
2410
      case record_reg:
2411
        save_size += 1 + 4 + record_list->u.reg.len;
2412
        break;
2413
      case record_mem:
2414
        save_size += 1 + 4 + 8 + record_list->u.mem.len;
2415
        break;
2416
      }
2417
 
2418
  /* Make the new bfd section.  */
2419
  osec = bfd_make_section_anyway_with_flags (obfd, "precord",
2420
                                             SEC_HAS_CONTENTS
2421
                                             | SEC_READONLY);
2422
  if (osec == NULL)
2423
    error (_("Failed to create 'precord' section for corefile %s: %s"),
2424
           recfilename,
2425
           bfd_errmsg (bfd_get_error ()));
2426
  bfd_set_section_size (obfd, osec, save_size);
2427
  bfd_set_section_vma (obfd, osec, 0);
2428
  bfd_set_section_alignment (obfd, osec, 0);
2429
  bfd_section_lma (obfd, osec) = 0;
2430
 
2431
  /* Save corefile state.  */
2432
  write_gcore_file (obfd);
2433
 
2434
  /* Write out the record log.  */
2435
  /* Write the magic code.  */
2436
  magic = RECORD_FILE_MAGIC;
2437
  if (record_debug)
2438
    fprintf_unfiltered (gdb_stdlog, "\
2439
  Writing 4-byte magic cookie RECORD_FILE_MAGIC (0x%s)\n",
2440
                      phex_nz (magic, 4));
2441
  bfdcore_write (obfd, osec, &magic, sizeof (magic), &bfd_offset);
2442
 
2443
  /* Save the entries to recfd and forward execute to the end of
2444
     record list.  */
2445
  record_list = &record_first;
2446
  while (1)
2447
    {
2448
      /* Save entry.  */
2449
      if (record_list != &record_first)
2450
        {
2451
          uint8_t type;
2452
          uint32_t regnum, len, signal, count;
2453
          uint64_t addr;
2454
 
2455
          type = record_list->type;
2456
          bfdcore_write (obfd, osec, &type, sizeof (type), &bfd_offset);
2457
 
2458
          switch (record_list->type)
2459
            {
2460
            case record_reg: /* reg */
2461
              if (record_debug)
2462
                fprintf_unfiltered (gdb_stdlog, "\
2463
  Writing register %d (1 plus %lu plus %d bytes)\n",
2464
                                    record_list->u.reg.num,
2465
                                    (unsigned long) sizeof (regnum),
2466
                                    record_list->u.reg.len);
2467
 
2468
              /* Write regnum.  */
2469
              regnum = netorder32 (record_list->u.reg.num);
2470
              bfdcore_write (obfd, osec, &regnum,
2471
                             sizeof (regnum), &bfd_offset);
2472
 
2473
              /* Write regval.  */
2474
              bfdcore_write (obfd, osec, record_get_loc (record_list),
2475
                             record_list->u.reg.len, &bfd_offset);
2476
              break;
2477
 
2478
            case record_mem: /* mem */
2479
              if (record_debug)
2480
                fprintf_unfiltered (gdb_stdlog, "\
2481
  Writing memory %s (1 plus %lu plus %lu plus %d bytes)\n",
2482
                                    paddress (gdbarch,
2483
                                              record_list->u.mem.addr),
2484
                                    (unsigned long) sizeof (addr),
2485
                                    (unsigned long) sizeof (len),
2486
                                    record_list->u.mem.len);
2487
 
2488
              /* Write memlen.  */
2489
              len = netorder32 (record_list->u.mem.len);
2490
              bfdcore_write (obfd, osec, &len, sizeof (len), &bfd_offset);
2491
 
2492
              /* Write memaddr.  */
2493
              addr = netorder64 (record_list->u.mem.addr);
2494
              bfdcore_write (obfd, osec, &addr,
2495
                             sizeof (addr), &bfd_offset);
2496
 
2497
              /* Write memval.  */
2498
              bfdcore_write (obfd, osec, record_get_loc (record_list),
2499
                             record_list->u.mem.len, &bfd_offset);
2500
              break;
2501
 
2502
              case record_end:
2503
                if (record_debug)
2504
                  fprintf_unfiltered (gdb_stdlog, "\
2505
  Writing record_end (1 + %lu + %lu bytes)\n",
2506
                                      (unsigned long) sizeof (signal),
2507
                                      (unsigned long) sizeof (count));
2508
                /* Write signal value.  */
2509
                signal = netorder32 (record_list->u.end.sigval);
2510
                bfdcore_write (obfd, osec, &signal,
2511
                               sizeof (signal), &bfd_offset);
2512
 
2513
                /* Write insn count.  */
2514
                count = netorder32 (record_list->u.end.insn_num);
2515
                bfdcore_write (obfd, osec, &count,
2516
                               sizeof (count), &bfd_offset);
2517
                break;
2518
            }
2519
        }
2520
 
2521
      /* Execute entry.  */
2522
      record_exec_insn (regcache, gdbarch, record_list);
2523
 
2524
      if (record_list->next)
2525
        record_list = record_list->next;
2526
      else
2527
        break;
2528
    }
2529
 
2530
  /* Reverse execute to cur_record_list.  */
2531
  while (1)
2532
    {
2533
      /* Check for beginning and end of log.  */
2534
      if (record_list == cur_record_list)
2535
        break;
2536
 
2537
      record_exec_insn (regcache, gdbarch, record_list);
2538
 
2539
      if (record_list->prev)
2540
        record_list = record_list->prev;
2541
    }
2542
 
2543
  do_cleanups (set_cleanups);
2544
  bfd_close (obfd);
2545
  discard_cleanups (old_cleanups);
2546
 
2547
  /* Succeeded.  */
2548
  printf_filtered (_("Saved core file %s with execution log.\n"),
2549
                   recfilename);
2550
}
2551
 
2552
/* record_goto_insn -- rewind the record log (forward or backward,
2553
   depending on DIR) to the given entry, changing the program state
2554
   correspondingly.  */
2555
 
2556
static void
2557
record_goto_insn (struct record_entry *entry,
2558
                  enum exec_direction_kind dir)
2559
{
2560
  struct cleanup *set_cleanups = record_gdb_operation_disable_set ();
2561
  struct regcache *regcache = get_current_regcache ();
2562
  struct gdbarch *gdbarch = get_regcache_arch (regcache);
2563
 
2564
  /* Assume everything is valid: we will hit the entry,
2565
     and we will not hit the end of the recording.  */
2566
 
2567
  if (dir == EXEC_FORWARD)
2568
    record_list = record_list->next;
2569
 
2570
  do
2571
    {
2572
      record_exec_insn (regcache, gdbarch, record_list);
2573
      if (dir == EXEC_REVERSE)
2574
        record_list = record_list->prev;
2575
      else
2576
        record_list = record_list->next;
2577
    } while (record_list != entry);
2578
  do_cleanups (set_cleanups);
2579
}
2580
 
2581
/* "record goto" command.  Argument is an instruction number,
2582
   as given by "info record".
2583
 
2584
   Rewinds the recording (forward or backward) to the given instruction.  */
2585
 
2586
static void
2587
cmd_record_goto (char *arg, int from_tty)
2588
{
2589
  struct record_entry *p = NULL;
2590
  ULONGEST target_insn = 0;
2591
 
2592
  if (arg == NULL || *arg == '\0')
2593
    error (_("Command requires an argument (insn number to go to)."));
2594
 
2595
  if (strncmp (arg, "start", strlen ("start")) == 0
2596
      || strncmp (arg, "begin", strlen ("begin")) == 0)
2597
    {
2598
      /* Special case.  Find first insn.  */
2599
      for (p = &record_first; p != NULL; p = p->next)
2600
        if (p->type == record_end)
2601
          break;
2602
      if (p)
2603
        target_insn = p->u.end.insn_num;
2604
    }
2605
  else if (strncmp (arg, "end", strlen ("end")) == 0)
2606
    {
2607
      /* Special case.  Find last insn.  */
2608
      for (p = record_list; p->next != NULL; p = p->next)
2609
        ;
2610
      for (; p!= NULL; p = p->prev)
2611
        if (p->type == record_end)
2612
          break;
2613
      if (p)
2614
        target_insn = p->u.end.insn_num;
2615
    }
2616
  else
2617
    {
2618
      /* General case.  Find designated insn.  */
2619
      target_insn = parse_and_eval_long (arg);
2620
 
2621
      for (p = &record_first; p != NULL; p = p->next)
2622
        if (p->type == record_end && p->u.end.insn_num == target_insn)
2623
          break;
2624
    }
2625
 
2626
  if (p == NULL)
2627
    error (_("Target insn '%s' not found."), arg);
2628
  else if (p == record_list)
2629
    error (_("Already at insn '%s'."), arg);
2630
  else if (p->u.end.insn_num > record_list->u.end.insn_num)
2631
    {
2632
      printf_filtered (_("Go forward to insn number %s\n"),
2633
                       pulongest (target_insn));
2634
      record_goto_insn (p, EXEC_FORWARD);
2635
    }
2636
  else
2637
    {
2638
      printf_filtered (_("Go backward to insn number %s\n"),
2639
                       pulongest (target_insn));
2640
      record_goto_insn (p, EXEC_REVERSE);
2641
    }
2642
  registers_changed ();
2643
  reinit_frame_cache ();
2644
  print_stack_frame (get_selected_frame (NULL), 1, SRC_AND_LOC);
2645
}
2646
 
2647
void
2648
_initialize_record (void)
2649
{
2650
  struct cmd_list_element *c;
2651
 
2652
  /* Init record_first.  */
2653
  record_first.prev = NULL;
2654
  record_first.next = NULL;
2655
  record_first.type = record_end;
2656
 
2657
  init_record_ops ();
2658
  add_target (&record_ops);
2659
  init_record_core_ops ();
2660
  add_target (&record_core_ops);
2661
 
2662
  add_setshow_zinteger_cmd ("record", no_class, &record_debug,
2663
                            _("Set debugging of record/replay feature."),
2664
                            _("Show debugging of record/replay feature."),
2665
                            _("When enabled, debugging output for "
2666
                              "record/replay feature is displayed."),
2667
                            NULL, show_record_debug, &setdebuglist,
2668
                            &showdebuglist);
2669
 
2670
  c = add_prefix_cmd ("record", class_obscure, cmd_record_start,
2671
                      _("Abbreviated form of \"target record\" command."),
2672
                      &record_cmdlist, "record ", 0, &cmdlist);
2673
  set_cmd_completer (c, filename_completer);
2674
 
2675
  add_com_alias ("rec", "record", class_obscure, 1);
2676
  add_prefix_cmd ("record", class_support, set_record_command,
2677
                  _("Set record options"), &set_record_cmdlist,
2678
                  "set record ", 0, &setlist);
2679
  add_alias_cmd ("rec", "record", class_obscure, 1, &setlist);
2680
  add_prefix_cmd ("record", class_support, show_record_command,
2681
                  _("Show record options"), &show_record_cmdlist,
2682
                  "show record ", 0, &showlist);
2683
  add_alias_cmd ("rec", "record", class_obscure, 1, &showlist);
2684
  add_prefix_cmd ("record", class_support, info_record_command,
2685
                  _("Info record options"), &info_record_cmdlist,
2686
                  "info record ", 0, &infolist);
2687
  add_alias_cmd ("rec", "record", class_obscure, 1, &infolist);
2688
 
2689
  c = add_cmd ("save", class_obscure, cmd_record_save,
2690
               _("Save the execution log to a file.\n\
2691
Argument is optional filename.\n\
2692
Default filename is 'gdb_record.<process_id>'."),
2693
               &record_cmdlist);
2694
  set_cmd_completer (c, filename_completer);
2695
 
2696
  c = add_cmd ("restore", class_obscure, cmd_record_restore,
2697
               _("Restore the execution log from a file.\n\
2698
Argument is filename.  File must be created with 'record save'."),
2699
               &record_cmdlist);
2700
  set_cmd_completer (c, filename_completer);
2701
 
2702
  add_cmd ("delete", class_obscure, cmd_record_delete,
2703
           _("Delete the rest of execution log and start recording it anew."),
2704
           &record_cmdlist);
2705
  add_alias_cmd ("d", "delete", class_obscure, 1, &record_cmdlist);
2706
  add_alias_cmd ("del", "delete", class_obscure, 1, &record_cmdlist);
2707
 
2708
  add_cmd ("stop", class_obscure, cmd_record_stop,
2709
           _("Stop the record/replay target."),
2710
           &record_cmdlist);
2711
  add_alias_cmd ("s", "stop", class_obscure, 1, &record_cmdlist);
2712
 
2713
  /* Record instructions number limit command.  */
2714
  add_setshow_boolean_cmd ("stop-at-limit", no_class,
2715
                           &record_stop_at_limit, _("\
2716
Set whether record/replay stops when record/replay buffer becomes full."), _("\
2717
Show whether record/replay stops when record/replay buffer becomes full."), _("\
2718
Default is ON.\n\
2719
When ON, if the record/replay buffer becomes full, ask user what to do.\n\
2720
When OFF, if the record/replay buffer becomes full,\n\
2721
delete the oldest recorded instruction to make room for each new one."),
2722
                           NULL, NULL,
2723
                           &set_record_cmdlist, &show_record_cmdlist);
2724
  add_setshow_uinteger_cmd ("insn-number-max", no_class,
2725
                            &record_insn_max_num,
2726
                            _("Set record/replay buffer limit."),
2727
                            _("Show record/replay buffer limit."), _("\
2728
Set the maximum number of instructions to be stored in the\n\
2729
record/replay buffer.  Zero means unlimited.  Default is 200000."),
2730
                            set_record_insn_max_num,
2731
                            NULL, &set_record_cmdlist, &show_record_cmdlist);
2732
 
2733
  add_cmd ("goto", class_obscure, cmd_record_goto, _("\
2734
Restore the program to its state at instruction number N.\n\
2735
Argument is instruction number, as shown by 'info record'."),
2736
           &record_cmdlist);
2737
 
2738
  add_setshow_boolean_cmd ("memory-query", no_class,
2739
                           &record_memory_query, _("\
2740
Set whether query if PREC cannot record memory change of next instruction."),
2741
                           _("\
2742
Show whether query if PREC cannot record memory change of next instruction."),
2743
                           _("\
2744
Default is OFF.\n\
2745
When ON, query if PREC cannot record memory change of next instruction."),
2746
                           NULL, NULL,
2747
                           &set_record_cmdlist, &show_record_cmdlist);
2748
 
2749
}

powered by: WebSVN 2.1.0

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