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