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