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