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