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