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