GDB (API)
/home/stan/gdb/src/gdb/record-full.c
Go to the documentation of this file.
00001 /* Process record and replay target for GDB, the GNU debugger.
00002 
00003    Copyright (C) 2013 Free Software Foundation, Inc.
00004 
00005    This file is part of GDB.
00006 
00007    This program is free software; you can redistribute it and/or modify
00008    it under the terms of the GNU General Public License as published by
00009    the Free Software Foundation; either version 3 of the License, or
00010    (at your option) any later version.
00011 
00012    This program is distributed in the hope that it will be useful,
00013    but WITHOUT ANY WARRANTY; without even the implied warranty of
00014    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015    GNU General Public License for more details.
00016 
00017    You should have received a copy of the GNU General Public License
00018    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
00019 
00020 #include "defs.h"
00021 #include "gdbcmd.h"
00022 #include "regcache.h"
00023 #include "gdbthread.h"
00024 #include "event-top.h"
00025 #include "exceptions.h"
00026 #include "completer.h"
00027 #include "arch-utils.h"
00028 #include "gdbcore.h"
00029 #include "exec.h"
00030 #include "record.h"
00031 #include "record-full.h"
00032 #include "elf-bfd.h"
00033 #include "gcore.h"
00034 #include "event-loop.h"
00035 #include "inf-loop.h"
00036 #include "gdb_bfd.h"
00037 #include "observer.h"
00038 
00039 #include <signal.h>
00040 
00041 /* This module implements "target record-full", also known as "process
00042    record and replay".  This target sits on top of a "normal" target
00043    (a target that "has execution"), and provides a record and replay
00044    functionality, including reverse debugging.
00045 
00046    Target record has two modes: recording, and replaying.
00047 
00048    In record mode, we intercept the to_resume and to_wait methods.
00049    Whenever gdb resumes the target, we run the target in single step
00050    mode, and we build up an execution log in which, for each executed
00051    instruction, we record all changes in memory and register state.
00052    This is invisible to the user, to whom it just looks like an
00053    ordinary debugging session (except for performance degredation).
00054 
00055    In replay mode, instead of actually letting the inferior run as a
00056    process, we simulate its execution by playing back the recorded
00057    execution log.  For each instruction in the log, we simulate the
00058    instruction's side effects by duplicating the changes that it would
00059    have made on memory and registers.  */
00060 
00061 #define DEFAULT_RECORD_FULL_INSN_MAX_NUM        200000
00062 
00063 #define RECORD_FULL_IS_REPLAY \
00064      (record_full_list->next || execution_direction == EXEC_REVERSE)
00065 
00066 #define RECORD_FULL_FILE_MAGIC  netorder32(0x20091016)
00067 
00068 /* These are the core structs of the process record functionality.
00069 
00070    A record_full_entry is a record of the value change of a register
00071    ("record_full_reg") or a part of memory ("record_full_mem").  And each
00072    instruction must have a struct record_full_entry ("record_full_end")
00073    that indicates that this is the last struct record_full_entry of this
00074    instruction.
00075 
00076    Each struct record_full_entry is linked to "record_full_list" by "prev"
00077    and "next" pointers.  */
00078 
00079 struct record_full_mem_entry
00080 {
00081   CORE_ADDR addr;
00082   int len;
00083   /* Set this flag if target memory for this entry
00084      can no longer be accessed.  */
00085   int mem_entry_not_accessible;
00086   union
00087   {
00088     gdb_byte *ptr;
00089     gdb_byte buf[sizeof (gdb_byte *)];
00090   } u;
00091 };
00092 
00093 struct record_full_reg_entry
00094 {
00095   unsigned short num;
00096   unsigned short len;
00097   union 
00098   {
00099     gdb_byte *ptr;
00100     gdb_byte buf[2 * sizeof (gdb_byte *)];
00101   } u;
00102 };
00103 
00104 struct record_full_end_entry
00105 {
00106   enum gdb_signal sigval;
00107   ULONGEST insn_num;
00108 };
00109 
00110 enum record_full_type
00111 {
00112   record_full_end = 0,
00113   record_full_reg,
00114   record_full_mem
00115 };
00116 
00117 /* This is the data structure that makes up the execution log.
00118 
00119    The execution log consists of a single linked list of entries
00120    of type "struct record_full_entry".  It is doubly linked so that it
00121    can be traversed in either direction.
00122 
00123    The start of the list is anchored by a struct called
00124    "record_full_first".  The pointer "record_full_list" either points
00125    to the last entry that was added to the list (in record mode), or to
00126    the next entry in the list that will be executed (in replay mode).
00127 
00128    Each list element (struct record_full_entry), in addition to next
00129    and prev pointers, consists of a union of three entry types: mem,
00130    reg, and end.  A field called "type" determines which entry type is
00131    represented by a given list element.
00132 
00133    Each instruction that is added to the execution log is represented
00134    by a variable number of list elements ('entries').  The instruction
00135    will have one "reg" entry for each register that is changed by 
00136    executing the instruction (including the PC in every case).  It 
00137    will also have one "mem" entry for each memory change.  Finally,
00138    each instruction will have an "end" entry that separates it from
00139    the changes associated with the next instruction.  */
00140 
00141 struct record_full_entry
00142 {
00143   struct record_full_entry *prev;
00144   struct record_full_entry *next;
00145   enum record_full_type type;
00146   union
00147   {
00148     /* reg */
00149     struct record_full_reg_entry reg;
00150     /* mem */
00151     struct record_full_mem_entry mem;
00152     /* end */
00153     struct record_full_end_entry end;
00154   } u;
00155 };
00156 
00157 /* If true, query if PREC cannot record memory
00158    change of next instruction.  */
00159 int record_full_memory_query = 0;
00160 
00161 struct record_full_core_buf_entry
00162 {
00163   struct record_full_core_buf_entry *prev;
00164   struct target_section *p;
00165   bfd_byte *buf;
00166 };
00167 
00168 /* Record buf with core target.  */
00169 static gdb_byte *record_full_core_regbuf = NULL;
00170 static struct target_section *record_full_core_start;
00171 static struct target_section *record_full_core_end;
00172 static struct record_full_core_buf_entry *record_full_core_buf_list = NULL;
00173 
00174 /* The following variables are used for managing the linked list that
00175    represents the execution log.
00176 
00177    record_full_first is the anchor that holds down the beginning of
00178    the list.
00179 
00180    record_full_list serves two functions:
00181      1) In record mode, it anchors the end of the list.
00182      2) In replay mode, it traverses the list and points to
00183         the next instruction that must be emulated.
00184 
00185    record_full_arch_list_head and record_full_arch_list_tail are used
00186    to manage a separate list, which is used to build up the change
00187    elements of the currently executing instruction during record mode.
00188    When this instruction has been completely annotated in the "arch
00189    list", it will be appended to the main execution log.  */
00190 
00191 static struct record_full_entry record_full_first;
00192 static struct record_full_entry *record_full_list = &record_full_first;
00193 static struct record_full_entry *record_full_arch_list_head = NULL;
00194 static struct record_full_entry *record_full_arch_list_tail = NULL;
00195 
00196 /* 1 ask user. 0 auto delete the last struct record_full_entry.  */
00197 static int record_full_stop_at_limit = 1;
00198 /* Maximum allowed number of insns in execution log.  */
00199 static unsigned int record_full_insn_max_num
00200         = DEFAULT_RECORD_FULL_INSN_MAX_NUM;
00201 /* Actual count of insns presently in execution log.  */
00202 static unsigned int record_full_insn_num = 0;
00203 /* Count of insns logged so far (may be larger
00204    than count of insns presently in execution log).  */
00205 static ULONGEST record_full_insn_count;
00206 
00207 /* The target_ops of process record.  */
00208 static struct target_ops record_full_ops;
00209 static struct target_ops record_full_core_ops;
00210 
00211 /* Command lists for "set/show record full".  */
00212 static struct cmd_list_element *set_record_full_cmdlist;
00213 static struct cmd_list_element *show_record_full_cmdlist;
00214 
00215 /* Command list for "record full".  */
00216 static struct cmd_list_element *record_full_cmdlist;
00217 
00218 /* The beneath function pointers.  */
00219 static struct target_ops *record_full_beneath_to_resume_ops;
00220 static void (*record_full_beneath_to_resume) (struct target_ops *, ptid_t, int,
00221                                               enum gdb_signal);
00222 static struct target_ops *record_full_beneath_to_wait_ops;
00223 static ptid_t (*record_full_beneath_to_wait) (struct target_ops *, ptid_t,
00224                                               struct target_waitstatus *,
00225                                               int);
00226 static struct target_ops *record_full_beneath_to_store_registers_ops;
00227 static void (*record_full_beneath_to_store_registers) (struct target_ops *,
00228                                                        struct regcache *,
00229                                                        int regno);
00230 static struct target_ops *record_full_beneath_to_xfer_partial_ops;
00231 static LONGEST
00232   (*record_full_beneath_to_xfer_partial) (struct target_ops *ops,
00233                                           enum target_object object,
00234                                           const char *annex,
00235                                           gdb_byte *readbuf,
00236                                           const gdb_byte *writebuf,
00237                                           ULONGEST offset,
00238                                           LONGEST len);
00239 static int
00240   (*record_full_beneath_to_insert_breakpoint) (struct gdbarch *,
00241                                                struct bp_target_info *);
00242 static int
00243   (*record_full_beneath_to_remove_breakpoint) (struct gdbarch *,
00244                                                struct bp_target_info *);
00245 static int (*record_full_beneath_to_stopped_by_watchpoint) (void);
00246 static int (*record_full_beneath_to_stopped_data_address) (struct target_ops *,
00247                                                            CORE_ADDR *);
00248 static void
00249   (*record_full_beneath_to_async) (void (*) (enum inferior_event_type, void *),
00250                                    void *);
00251 
00252 static void record_full_goto_insn (struct record_full_entry *entry,
00253                                    enum exec_direction_kind dir);
00254 static void record_full_save (const char *recfilename);
00255 
00256 /* Alloc and free functions for record_full_reg, record_full_mem, and
00257    record_full_end entries.  */
00258 
00259 /* Alloc a record_full_reg record entry.  */
00260 
00261 static inline struct record_full_entry *
00262 record_full_reg_alloc (struct regcache *regcache, int regnum)
00263 {
00264   struct record_full_entry *rec;
00265   struct gdbarch *gdbarch = get_regcache_arch (regcache);
00266 
00267   rec = xcalloc (1, sizeof (struct record_full_entry));
00268   rec->type = record_full_reg;
00269   rec->u.reg.num = regnum;
00270   rec->u.reg.len = register_size (gdbarch, regnum);
00271   if (rec->u.reg.len > sizeof (rec->u.reg.u.buf))
00272     rec->u.reg.u.ptr = (gdb_byte *) xmalloc (rec->u.reg.len);
00273 
00274   return rec;
00275 }
00276 
00277 /* Free a record_full_reg record entry.  */
00278 
00279 static inline void
00280 record_full_reg_release (struct record_full_entry *rec)
00281 {
00282   gdb_assert (rec->type == record_full_reg);
00283   if (rec->u.reg.len > sizeof (rec->u.reg.u.buf))
00284     xfree (rec->u.reg.u.ptr);
00285   xfree (rec);
00286 }
00287 
00288 /* Alloc a record_full_mem record entry.  */
00289 
00290 static inline struct record_full_entry *
00291 record_full_mem_alloc (CORE_ADDR addr, int len)
00292 {
00293   struct record_full_entry *rec;
00294 
00295   rec = xcalloc (1, sizeof (struct record_full_entry));
00296   rec->type = record_full_mem;
00297   rec->u.mem.addr = addr;
00298   rec->u.mem.len = len;
00299   if (rec->u.mem.len > sizeof (rec->u.mem.u.buf))
00300     rec->u.mem.u.ptr = (gdb_byte *) xmalloc (len);
00301 
00302   return rec;
00303 }
00304 
00305 /* Free a record_full_mem record entry.  */
00306 
00307 static inline void
00308 record_full_mem_release (struct record_full_entry *rec)
00309 {
00310   gdb_assert (rec->type == record_full_mem);
00311   if (rec->u.mem.len > sizeof (rec->u.mem.u.buf))
00312     xfree (rec->u.mem.u.ptr);
00313   xfree (rec);
00314 }
00315 
00316 /* Alloc a record_full_end record entry.  */
00317 
00318 static inline struct record_full_entry *
00319 record_full_end_alloc (void)
00320 {
00321   struct record_full_entry *rec;
00322 
00323   rec = xcalloc (1, sizeof (struct record_full_entry));
00324   rec->type = record_full_end;
00325 
00326   return rec;
00327 }
00328 
00329 /* Free a record_full_end record entry.  */
00330 
00331 static inline void
00332 record_full_end_release (struct record_full_entry *rec)
00333 {
00334   xfree (rec);
00335 }
00336 
00337 /* Free one record entry, any type.
00338    Return entry->type, in case caller wants to know.  */
00339 
00340 static inline enum record_full_type
00341 record_full_entry_release (struct record_full_entry *rec)
00342 {
00343   enum record_full_type type = rec->type;
00344 
00345   switch (type) {
00346   case record_full_reg:
00347     record_full_reg_release (rec);
00348     break;
00349   case record_full_mem:
00350     record_full_mem_release (rec);
00351     break;
00352   case record_full_end:
00353     record_full_end_release (rec);
00354     break;
00355   }
00356   return type;
00357 }
00358 
00359 /* Free all record entries in list pointed to by REC.  */
00360 
00361 static void
00362 record_full_list_release (struct record_full_entry *rec)
00363 {
00364   if (!rec)
00365     return;
00366 
00367   while (rec->next)
00368     rec = rec->next;
00369 
00370   while (rec->prev)
00371     {
00372       rec = rec->prev;
00373       record_full_entry_release (rec->next);
00374     }
00375 
00376   if (rec == &record_full_first)
00377     {
00378       record_full_insn_num = 0;
00379       record_full_first.next = NULL;
00380     }
00381   else
00382     record_full_entry_release (rec);
00383 }
00384 
00385 /* Free all record entries forward of the given list position.  */
00386 
00387 static void
00388 record_full_list_release_following (struct record_full_entry *rec)
00389 {
00390   struct record_full_entry *tmp = rec->next;
00391 
00392   rec->next = NULL;
00393   while (tmp)
00394     {
00395       rec = tmp->next;
00396       if (record_full_entry_release (tmp) == record_full_end)
00397         {
00398           record_full_insn_num--;
00399           record_full_insn_count--;
00400         }
00401       tmp = rec;
00402     }
00403 }
00404 
00405 /* Delete the first instruction from the beginning of the log, to make
00406    room for adding a new instruction at the end of the log.
00407 
00408    Note -- this function does not modify record_full_insn_num.  */
00409 
00410 static void
00411 record_full_list_release_first (void)
00412 {
00413   struct record_full_entry *tmp;
00414 
00415   if (!record_full_first.next)
00416     return;
00417 
00418   /* Loop until a record_full_end.  */
00419   while (1)
00420     {
00421       /* Cut record_full_first.next out of the linked list.  */
00422       tmp = record_full_first.next;
00423       record_full_first.next = tmp->next;
00424       tmp->next->prev = &record_full_first;
00425 
00426       /* tmp is now isolated, and can be deleted.  */
00427       if (record_full_entry_release (tmp) == record_full_end)
00428         break;  /* End loop at first record_full_end.  */
00429 
00430       if (!record_full_first.next)
00431         {
00432           gdb_assert (record_full_insn_num == 1);
00433           break;        /* End loop when list is empty.  */
00434         }
00435     }
00436 }
00437 
00438 /* Add a struct record_full_entry to record_full_arch_list.  */
00439 
00440 static void
00441 record_full_arch_list_add (struct record_full_entry *rec)
00442 {
00443   if (record_debug > 1)
00444     fprintf_unfiltered (gdb_stdlog,
00445                         "Process record: record_full_arch_list_add %s.\n",
00446                         host_address_to_string (rec));
00447 
00448   if (record_full_arch_list_tail)
00449     {
00450       record_full_arch_list_tail->next = rec;
00451       rec->prev = record_full_arch_list_tail;
00452       record_full_arch_list_tail = rec;
00453     }
00454   else
00455     {
00456       record_full_arch_list_head = rec;
00457       record_full_arch_list_tail = rec;
00458     }
00459 }
00460 
00461 /* Return the value storage location of a record entry.  */
00462 static inline gdb_byte *
00463 record_full_get_loc (struct record_full_entry *rec)
00464 {
00465   switch (rec->type) {
00466   case record_full_mem:
00467     if (rec->u.mem.len > sizeof (rec->u.mem.u.buf))
00468       return rec->u.mem.u.ptr;
00469     else
00470       return rec->u.mem.u.buf;
00471   case record_full_reg:
00472     if (rec->u.reg.len > sizeof (rec->u.reg.u.buf))
00473       return rec->u.reg.u.ptr;
00474     else
00475       return rec->u.reg.u.buf;
00476   case record_full_end:
00477   default:
00478     gdb_assert_not_reached ("unexpected record_full_entry type");
00479     return NULL;
00480   }
00481 }
00482 
00483 /* Record the value of a register NUM to record_full_arch_list.  */
00484 
00485 int
00486 record_full_arch_list_add_reg (struct regcache *regcache, int regnum)
00487 {
00488   struct record_full_entry *rec;
00489 
00490   if (record_debug > 1)
00491     fprintf_unfiltered (gdb_stdlog,
00492                         "Process record: add register num = %d to "
00493                         "record list.\n",
00494                         regnum);
00495 
00496   rec = record_full_reg_alloc (regcache, regnum);
00497 
00498   regcache_raw_read (regcache, regnum, record_full_get_loc (rec));
00499 
00500   record_full_arch_list_add (rec);
00501 
00502   return 0;
00503 }
00504 
00505 /* Record the value of a region of memory whose address is ADDR and
00506    length is LEN to record_full_arch_list.  */
00507 
00508 int
00509 record_full_arch_list_add_mem (CORE_ADDR addr, int len)
00510 {
00511   struct record_full_entry *rec;
00512 
00513   if (record_debug > 1)
00514     fprintf_unfiltered (gdb_stdlog,
00515                         "Process record: add mem addr = %s len = %d to "
00516                         "record list.\n",
00517                         paddress (target_gdbarch (), addr), len);
00518 
00519   if (!addr)    /* FIXME: Why?  Some arch must permit it...  */
00520     return 0;
00521 
00522   rec = record_full_mem_alloc (addr, len);
00523 
00524   if (record_read_memory (target_gdbarch (), addr,
00525                           record_full_get_loc (rec), len))
00526     {
00527       record_full_mem_release (rec);
00528       return -1;
00529     }
00530 
00531   record_full_arch_list_add (rec);
00532 
00533   return 0;
00534 }
00535 
00536 /* Add a record_full_end type struct record_full_entry to
00537    record_full_arch_list.  */
00538 
00539 int
00540 record_full_arch_list_add_end (void)
00541 {
00542   struct record_full_entry *rec;
00543 
00544   if (record_debug > 1)
00545     fprintf_unfiltered (gdb_stdlog,
00546                         "Process record: add end to arch list.\n");
00547 
00548   rec = record_full_end_alloc ();
00549   rec->u.end.sigval = GDB_SIGNAL_0;
00550   rec->u.end.insn_num = ++record_full_insn_count;
00551 
00552   record_full_arch_list_add (rec);
00553 
00554   return 0;
00555 }
00556 
00557 static void
00558 record_full_check_insn_num (int set_terminal)
00559 {
00560   if (record_full_insn_num == record_full_insn_max_num)
00561     {
00562       /* Ask user what to do.  */
00563       if (record_full_stop_at_limit)
00564         {
00565           int q;
00566 
00567           if (set_terminal)
00568             target_terminal_ours ();
00569           q = yquery (_("Do you want to auto delete previous execution "
00570                         "log entries when record/replay buffer becomes "
00571                         "full (record full stop-at-limit)?"));
00572           if (set_terminal)
00573             target_terminal_inferior ();
00574           if (q)
00575             record_full_stop_at_limit = 0;
00576           else
00577             error (_("Process record: stopped by user."));
00578         }
00579     }
00580 }
00581 
00582 static void
00583 record_full_arch_list_cleanups (void *ignore)
00584 {
00585   record_full_list_release (record_full_arch_list_tail);
00586 }
00587 
00588 /* Before inferior step (when GDB record the running message, inferior
00589    only can step), GDB will call this function to record the values to
00590    record_full_list.  This function will call gdbarch_process_record to
00591    record the running message of inferior and set them to
00592    record_full_arch_list, and add it to record_full_list.  */
00593 
00594 static int
00595 record_full_message (struct regcache *regcache, enum gdb_signal signal)
00596 {
00597   int ret;
00598   struct gdbarch *gdbarch = get_regcache_arch (regcache);
00599   struct cleanup *old_cleanups
00600     = make_cleanup (record_full_arch_list_cleanups, 0);
00601 
00602   record_full_arch_list_head = NULL;
00603   record_full_arch_list_tail = NULL;
00604 
00605   /* Check record_full_insn_num.  */
00606   record_full_check_insn_num (1);
00607 
00608   /* If gdb sends a signal value to target_resume,
00609      save it in the 'end' field of the previous instruction.
00610 
00611      Maybe process record should record what really happened,
00612      rather than what gdb pretends has happened.
00613 
00614      So if Linux delivered the signal to the child process during
00615      the record mode, we will record it and deliver it again in
00616      the replay mode.
00617 
00618      If user says "ignore this signal" during the record mode, then
00619      it will be ignored again during the replay mode (no matter if
00620      the user says something different, like "deliver this signal"
00621      during the replay mode).
00622 
00623      User should understand that nothing he does during the replay
00624      mode will change the behavior of the child.  If he tries,
00625      then that is a user error.
00626 
00627      But we should still deliver the signal to gdb during the replay,
00628      if we delivered it during the recording.  Therefore we should
00629      record the signal during record_full_wait, not
00630      record_full_resume.  */
00631   if (record_full_list != &record_full_first)  /* FIXME better way to check */
00632     {
00633       gdb_assert (record_full_list->type == record_full_end);
00634       record_full_list->u.end.sigval = signal;
00635     }
00636 
00637   if (signal == GDB_SIGNAL_0
00638       || !gdbarch_process_record_signal_p (gdbarch))
00639     ret = gdbarch_process_record (gdbarch,
00640                                   regcache,
00641                                   regcache_read_pc (regcache));
00642   else
00643     ret = gdbarch_process_record_signal (gdbarch,
00644                                          regcache,
00645                                          signal);
00646 
00647   if (ret > 0)
00648     error (_("Process record: inferior program stopped."));
00649   if (ret < 0)
00650     error (_("Process record: failed to record execution log."));
00651 
00652   discard_cleanups (old_cleanups);
00653 
00654   record_full_list->next = record_full_arch_list_head;
00655   record_full_arch_list_head->prev = record_full_list;
00656   record_full_list = record_full_arch_list_tail;
00657 
00658   if (record_full_insn_num == record_full_insn_max_num)
00659     record_full_list_release_first ();
00660   else
00661     record_full_insn_num++;
00662 
00663   return 1;
00664 }
00665 
00666 struct record_full_message_args {
00667   struct regcache *regcache;
00668   enum gdb_signal signal;
00669 };
00670 
00671 static int
00672 record_full_message_wrapper (void *args)
00673 {
00674   struct record_full_message_args *record_full_args = args;
00675 
00676   return record_full_message (record_full_args->regcache,
00677                               record_full_args->signal);
00678 }
00679 
00680 static int
00681 record_full_message_wrapper_safe (struct regcache *regcache,
00682                                   enum gdb_signal signal)
00683 {
00684   struct record_full_message_args args;
00685 
00686   args.regcache = regcache;
00687   args.signal = signal;
00688 
00689   return catch_errors (record_full_message_wrapper, &args, NULL,
00690                        RETURN_MASK_ALL);
00691 }
00692 
00693 /* Set to 1 if record_full_store_registers and record_full_xfer_partial
00694    doesn't need record.  */
00695 
00696 static int record_full_gdb_operation_disable = 0;
00697 
00698 struct cleanup *
00699 record_full_gdb_operation_disable_set (void)
00700 {
00701   struct cleanup *old_cleanups = NULL;
00702 
00703   old_cleanups =
00704     make_cleanup_restore_integer (&record_full_gdb_operation_disable);
00705   record_full_gdb_operation_disable = 1;
00706 
00707   return old_cleanups;
00708 }
00709 
00710 /* Flag set to TRUE for target_stopped_by_watchpoint.  */
00711 static int record_full_hw_watchpoint = 0;
00712 
00713 /* Execute one instruction from the record log.  Each instruction in
00714    the log will be represented by an arbitrary sequence of register
00715    entries and memory entries, followed by an 'end' entry.  */
00716 
00717 static inline void
00718 record_full_exec_insn (struct regcache *regcache,
00719                        struct gdbarch *gdbarch,
00720                        struct record_full_entry *entry)
00721 {
00722   switch (entry->type)
00723     {
00724     case record_full_reg: /* reg */
00725       {
00726         gdb_byte reg[MAX_REGISTER_SIZE];
00727 
00728         if (record_debug > 1)
00729           fprintf_unfiltered (gdb_stdlog,
00730                               "Process record: record_full_reg %s to "
00731                               "inferior num = %d.\n",
00732                               host_address_to_string (entry),
00733                               entry->u.reg.num);
00734 
00735         regcache_cooked_read (regcache, entry->u.reg.num, reg);
00736         regcache_cooked_write (regcache, entry->u.reg.num, 
00737                                record_full_get_loc (entry));
00738         memcpy (record_full_get_loc (entry), reg, entry->u.reg.len);
00739       }
00740       break;
00741 
00742     case record_full_mem: /* mem */
00743       {
00744         /* Nothing to do if the entry is flagged not_accessible.  */
00745         if (!entry->u.mem.mem_entry_not_accessible)
00746           {
00747             gdb_byte *mem = alloca (entry->u.mem.len);
00748 
00749             if (record_debug > 1)
00750               fprintf_unfiltered (gdb_stdlog,
00751                                   "Process record: record_full_mem %s to "
00752                                   "inferior addr = %s len = %d.\n",
00753                                   host_address_to_string (entry),
00754                                   paddress (gdbarch, entry->u.mem.addr),
00755                                   entry->u.mem.len);
00756 
00757             if (record_read_memory (gdbarch,
00758                                     entry->u.mem.addr, mem, entry->u.mem.len))
00759               entry->u.mem.mem_entry_not_accessible = 1;
00760             else
00761               {
00762                 if (target_write_memory (entry->u.mem.addr, 
00763                                          record_full_get_loc (entry),
00764                                          entry->u.mem.len))
00765                   {
00766                     entry->u.mem.mem_entry_not_accessible = 1;
00767                     if (record_debug)
00768                       warning (_("Process record: error writing memory at "
00769                                  "addr = %s len = %d."),
00770                                paddress (gdbarch, entry->u.mem.addr),
00771                                entry->u.mem.len);
00772                   }
00773                 else
00774                   {
00775                     memcpy (record_full_get_loc (entry), mem,
00776                             entry->u.mem.len);
00777 
00778                     /* We've changed memory --- check if a hardware
00779                        watchpoint should trap.  Note that this
00780                        presently assumes the target beneath supports
00781                        continuable watchpoints.  On non-continuable
00782                        watchpoints target, we'll want to check this
00783                        _before_ actually doing the memory change, and
00784                        not doing the change at all if the watchpoint
00785                        traps.  */
00786                     if (hardware_watchpoint_inserted_in_range
00787                         (get_regcache_aspace (regcache),
00788                          entry->u.mem.addr, entry->u.mem.len))
00789                       record_full_hw_watchpoint = 1;
00790                   }
00791               }
00792           }
00793       }
00794       break;
00795     }
00796 }
00797 
00798 static struct target_ops *tmp_to_resume_ops;
00799 static void (*tmp_to_resume) (struct target_ops *, ptid_t, int,
00800                               enum gdb_signal);
00801 static struct target_ops *tmp_to_wait_ops;
00802 static ptid_t (*tmp_to_wait) (struct target_ops *, ptid_t,
00803                               struct target_waitstatus *,
00804                               int);
00805 static struct target_ops *tmp_to_store_registers_ops;
00806 static void (*tmp_to_store_registers) (struct target_ops *,
00807                                        struct regcache *,
00808                                        int regno);
00809 static struct target_ops *tmp_to_xfer_partial_ops;
00810 static LONGEST (*tmp_to_xfer_partial) (struct target_ops *ops,
00811                                        enum target_object object,
00812                                        const char *annex,
00813                                        gdb_byte *readbuf,
00814                                        const gdb_byte *writebuf,
00815                                        ULONGEST offset,
00816                                        LONGEST len);
00817 static int (*tmp_to_insert_breakpoint) (struct gdbarch *,
00818                                         struct bp_target_info *);
00819 static int (*tmp_to_remove_breakpoint) (struct gdbarch *,
00820                                         struct bp_target_info *);
00821 static int (*tmp_to_stopped_by_watchpoint) (void);
00822 static int (*tmp_to_stopped_data_address) (struct target_ops *, CORE_ADDR *);
00823 static int (*tmp_to_stopped_data_address) (struct target_ops *, CORE_ADDR *);
00824 static void (*tmp_to_async) (void (*) (enum inferior_event_type, void *), void *);
00825 
00826 static void record_full_restore (void);
00827 
00828 /* Asynchronous signal handle registered as event loop source for when
00829    we have pending events ready to be passed to the core.  */
00830 
00831 static struct async_event_handler *record_full_async_inferior_event_token;
00832 
00833 static void
00834 record_full_async_inferior_event_handler (gdb_client_data data)
00835 {
00836   inferior_event_handler (INF_REG_EVENT, NULL);
00837 }
00838 
00839 /* Open the process record target.  */
00840 
00841 static void
00842 record_full_core_open_1 (char *name, int from_tty)
00843 {
00844   struct regcache *regcache = get_current_regcache ();
00845   int regnum = gdbarch_num_regs (get_regcache_arch (regcache));
00846   int i;
00847 
00848   /* Get record_full_core_regbuf.  */
00849   target_fetch_registers (regcache, -1);
00850   record_full_core_regbuf = xmalloc (MAX_REGISTER_SIZE * regnum);
00851   for (i = 0; i < regnum; i ++)
00852     regcache_raw_collect (regcache, i,
00853                           record_full_core_regbuf + MAX_REGISTER_SIZE * i);
00854 
00855   /* Get record_full_core_start and record_full_core_end.  */
00856   if (build_section_table (core_bfd, &record_full_core_start,
00857                            &record_full_core_end))
00858     {
00859       xfree (record_full_core_regbuf);
00860       record_full_core_regbuf = NULL;
00861       error (_("\"%s\": Can't find sections: %s"),
00862              bfd_get_filename (core_bfd), bfd_errmsg (bfd_get_error ()));
00863     }
00864 
00865   push_target (&record_full_core_ops);
00866   record_full_restore ();
00867 }
00868 
00869 /* "to_open" target method for 'live' processes.  */
00870 
00871 static void
00872 record_full_open_1 (char *name, int from_tty)
00873 {
00874   if (record_debug)
00875     fprintf_unfiltered (gdb_stdlog, "Process record: record_full_open\n");
00876 
00877   /* check exec */
00878   if (!target_has_execution)
00879     error (_("Process record: the program is not being run."));
00880   if (non_stop)
00881     error (_("Process record target can't debug inferior in non-stop mode "
00882              "(non-stop)."));
00883 
00884   if (!gdbarch_process_record_p (target_gdbarch ()))
00885     error (_("Process record: the current architecture doesn't support "
00886              "record function."));
00887 
00888   if (!tmp_to_resume)
00889     error (_("Could not find 'to_resume' method on the target stack."));
00890   if (!tmp_to_wait)
00891     error (_("Could not find 'to_wait' method on the target stack."));
00892   if (!tmp_to_store_registers)
00893     error (_("Could not find 'to_store_registers' "
00894              "method on the target stack."));
00895   if (!tmp_to_insert_breakpoint)
00896     error (_("Could not find 'to_insert_breakpoint' "
00897              "method on the target stack."));
00898   if (!tmp_to_remove_breakpoint)
00899     error (_("Could not find 'to_remove_breakpoint' "
00900              "method on the target stack."));
00901   if (!tmp_to_stopped_by_watchpoint)
00902     error (_("Could not find 'to_stopped_by_watchpoint' "
00903              "method on the target stack."));
00904   if (!tmp_to_stopped_data_address)
00905     error (_("Could not find 'to_stopped_data_address' "
00906              "method on the target stack."));
00907 
00908   push_target (&record_full_ops);
00909 }
00910 
00911 static void record_full_init_record_breakpoints (void);
00912 
00913 /* "to_open" target method.  Open the process record target.  */
00914 
00915 static void
00916 record_full_open (char *name, int from_tty)
00917 {
00918   struct target_ops *t;
00919 
00920   if (record_debug)
00921     fprintf_unfiltered (gdb_stdlog, "Process record: record_full_open\n");
00922 
00923   /* Check if record target is already running.  */
00924   if (current_target.to_stratum == record_stratum)
00925     error (_("Process record target already running.  Use \"record stop\" to "
00926              "stop record target first."));
00927 
00928   /* Reset the tmp beneath pointers.  */
00929   tmp_to_resume_ops = NULL;
00930   tmp_to_resume = NULL;
00931   tmp_to_wait_ops = NULL;
00932   tmp_to_wait = NULL;
00933   tmp_to_store_registers_ops = NULL;
00934   tmp_to_store_registers = NULL;
00935   tmp_to_xfer_partial_ops = NULL;
00936   tmp_to_xfer_partial = NULL;
00937   tmp_to_insert_breakpoint = NULL;
00938   tmp_to_remove_breakpoint = NULL;
00939   tmp_to_stopped_by_watchpoint = NULL;
00940   tmp_to_stopped_data_address = NULL;
00941   tmp_to_async = NULL;
00942 
00943   /* Set the beneath function pointers.  */
00944   for (t = current_target.beneath; t != NULL; t = t->beneath)
00945     {
00946       if (!tmp_to_resume)
00947         {
00948           tmp_to_resume = t->to_resume;
00949           tmp_to_resume_ops = t;
00950         }
00951       if (!tmp_to_wait)
00952         {
00953           tmp_to_wait = t->to_wait;
00954           tmp_to_wait_ops = t;
00955         }
00956       if (!tmp_to_store_registers)
00957         {
00958           tmp_to_store_registers = t->to_store_registers;
00959           tmp_to_store_registers_ops = t;
00960         }
00961       if (!tmp_to_xfer_partial)
00962         {
00963           tmp_to_xfer_partial = t->to_xfer_partial;
00964           tmp_to_xfer_partial_ops = t;
00965         }
00966       if (!tmp_to_insert_breakpoint)
00967         tmp_to_insert_breakpoint = t->to_insert_breakpoint;
00968       if (!tmp_to_remove_breakpoint)
00969         tmp_to_remove_breakpoint = t->to_remove_breakpoint;
00970       if (!tmp_to_stopped_by_watchpoint)
00971         tmp_to_stopped_by_watchpoint = t->to_stopped_by_watchpoint;
00972       if (!tmp_to_stopped_data_address)
00973         tmp_to_stopped_data_address = t->to_stopped_data_address;
00974       if (!tmp_to_async)
00975         tmp_to_async = t->to_async;
00976     }
00977   if (!tmp_to_xfer_partial)
00978     error (_("Could not find 'to_xfer_partial' method on the target stack."));
00979 
00980   /* Reset */
00981   record_full_insn_num = 0;
00982   record_full_insn_count = 0;
00983   record_full_list = &record_full_first;
00984   record_full_list->next = NULL;
00985 
00986   /* Set the tmp beneath pointers to beneath pointers.  */
00987   record_full_beneath_to_resume_ops = tmp_to_resume_ops;
00988   record_full_beneath_to_resume = tmp_to_resume;
00989   record_full_beneath_to_wait_ops = tmp_to_wait_ops;
00990   record_full_beneath_to_wait = tmp_to_wait;
00991   record_full_beneath_to_store_registers_ops = tmp_to_store_registers_ops;
00992   record_full_beneath_to_store_registers = tmp_to_store_registers;
00993   record_full_beneath_to_xfer_partial_ops = tmp_to_xfer_partial_ops;
00994   record_full_beneath_to_xfer_partial = tmp_to_xfer_partial;
00995   record_full_beneath_to_insert_breakpoint = tmp_to_insert_breakpoint;
00996   record_full_beneath_to_remove_breakpoint = tmp_to_remove_breakpoint;
00997   record_full_beneath_to_stopped_by_watchpoint = tmp_to_stopped_by_watchpoint;
00998   record_full_beneath_to_stopped_data_address = tmp_to_stopped_data_address;
00999   record_full_beneath_to_async = tmp_to_async;
01000 
01001   if (core_bfd)
01002     record_full_core_open_1 (name, from_tty);
01003   else
01004     record_full_open_1 (name, from_tty);
01005 
01006   /* Register extra event sources in the event loop.  */
01007   record_full_async_inferior_event_token
01008     = create_async_event_handler (record_full_async_inferior_event_handler,
01009                                   NULL);
01010 
01011   record_full_init_record_breakpoints ();
01012 
01013   observer_notify_record_changed (current_inferior (),  1);
01014 }
01015 
01016 /* "to_close" target method.  Close the process record target.  */
01017 
01018 static void
01019 record_full_close (void)
01020 {
01021   struct record_full_core_buf_entry *entry;
01022 
01023   if (record_debug)
01024     fprintf_unfiltered (gdb_stdlog, "Process record: record_full_close\n");
01025 
01026   record_full_list_release (record_full_list);
01027 
01028   /* Release record_full_core_regbuf.  */
01029   if (record_full_core_regbuf)
01030     {
01031       xfree (record_full_core_regbuf);
01032       record_full_core_regbuf = NULL;
01033     }
01034 
01035   /* Release record_full_core_buf_list.  */
01036   if (record_full_core_buf_list)
01037     {
01038       for (entry = record_full_core_buf_list->prev; entry;
01039            entry = entry->prev)
01040         {
01041           xfree (record_full_core_buf_list);
01042           record_full_core_buf_list = entry;
01043         }
01044       record_full_core_buf_list = NULL;
01045     }
01046 
01047   if (record_full_async_inferior_event_token)
01048     delete_async_event_handler (&record_full_async_inferior_event_token);
01049 }
01050 
01051 static int record_full_resume_step = 0;
01052 
01053 /* True if we've been resumed, and so each record_full_wait call should
01054    advance execution.  If this is false, record_full_wait will return a
01055    TARGET_WAITKIND_IGNORE.  */
01056 static int record_full_resumed = 0;
01057 
01058 /* The execution direction of the last resume we got.  This is
01059    necessary for async mode.  Vis (order is not strictly accurate):
01060 
01061    1. user has the global execution direction set to forward
01062    2. user does a reverse-step command
01063    3. record_full_resume is called with global execution direction
01064       temporarily switched to reverse
01065    4. GDB's execution direction is reverted back to forward
01066    5. target record notifies event loop there's an event to handle
01067    6. infrun asks the target which direction was it going, and switches
01068       the global execution direction accordingly (to reverse)
01069    7. infrun polls an event out of the record target, and handles it
01070    8. GDB goes back to the event loop, and goto #4.
01071 */
01072 static enum exec_direction_kind record_full_execution_dir = EXEC_FORWARD;
01073 
01074 /* "to_resume" target method.  Resume the process record target.  */
01075 
01076 static void
01077 record_full_resume (struct target_ops *ops, ptid_t ptid, int step,
01078                     enum gdb_signal signal)
01079 {
01080   record_full_resume_step = step;
01081   record_full_resumed = 1;
01082   record_full_execution_dir = execution_direction;
01083 
01084   if (!RECORD_FULL_IS_REPLAY)
01085     {
01086       struct gdbarch *gdbarch = target_thread_architecture (ptid);
01087 
01088       record_full_message (get_current_regcache (), signal);
01089 
01090       if (!step)
01091         {
01092           /* This is not hard single step.  */
01093           if (!gdbarch_software_single_step_p (gdbarch))
01094             {
01095               /* This is a normal continue.  */
01096               step = 1;
01097             }
01098           else
01099             {
01100               /* This arch support soft sigle step.  */
01101               if (single_step_breakpoints_inserted ())
01102                 {
01103                   /* This is a soft single step.  */
01104                   record_full_resume_step = 1;
01105                 }
01106               else
01107                 {
01108                   /* This is a continue.
01109                      Try to insert a soft single step breakpoint.  */
01110                   if (!gdbarch_software_single_step (gdbarch,
01111                                                      get_current_frame ()))
01112                     {
01113                       /* This system don't want use soft single step.
01114                          Use hard sigle step.  */
01115                       step = 1;
01116                     }
01117                 }
01118             }
01119         }
01120 
01121       /* Make sure the target beneath reports all signals.  */
01122       target_pass_signals (0, NULL);
01123 
01124       record_full_beneath_to_resume (record_full_beneath_to_resume_ops,
01125                                      ptid, step, signal);
01126     }
01127 
01128   /* We are about to start executing the inferior (or simulate it),
01129      let's register it with the event loop.  */
01130   if (target_can_async_p ())
01131     {
01132       target_async (inferior_event_handler, 0);
01133       /* Notify the event loop there's an event to wait for.  We do
01134          most of the work in record_full_wait.  */
01135       mark_async_event_handler (record_full_async_inferior_event_token);
01136     }
01137 }
01138 
01139 static int record_full_get_sig = 0;
01140 
01141 /* SIGINT signal handler, registered by "to_wait" method.  */
01142 
01143 static void
01144 record_full_sig_handler (int signo)
01145 {
01146   if (record_debug)
01147     fprintf_unfiltered (gdb_stdlog, "Process record: get a signal\n");
01148 
01149   /* It will break the running inferior in replay mode.  */
01150   record_full_resume_step = 1;
01151 
01152   /* It will let record_full_wait set inferior status to get the signal
01153      SIGINT.  */
01154   record_full_get_sig = 1;
01155 }
01156 
01157 static void
01158 record_full_wait_cleanups (void *ignore)
01159 {
01160   if (execution_direction == EXEC_REVERSE)
01161     {
01162       if (record_full_list->next)
01163         record_full_list = record_full_list->next;
01164     }
01165   else
01166     record_full_list = record_full_list->prev;
01167 }
01168 
01169 /* "to_wait" target method for process record target.
01170 
01171    In record mode, the target is always run in singlestep mode
01172    (even when gdb says to continue).  The to_wait method intercepts
01173    the stop events and determines which ones are to be passed on to
01174    gdb.  Most stop events are just singlestep events that gdb is not
01175    to know about, so the to_wait method just records them and keeps
01176    singlestepping.
01177 
01178    In replay mode, this function emulates the recorded execution log, 
01179    one instruction at a time (forward or backward), and determines 
01180    where to stop.  */
01181 
01182 static ptid_t
01183 record_full_wait_1 (struct target_ops *ops,
01184                     ptid_t ptid, struct target_waitstatus *status,
01185                     int options)
01186 {
01187   struct cleanup *set_cleanups = record_full_gdb_operation_disable_set ();
01188 
01189   if (record_debug)
01190     fprintf_unfiltered (gdb_stdlog,
01191                         "Process record: record_full_wait "
01192                         "record_full_resume_step = %d, "
01193                         "record_full_resumed = %d, direction=%s\n",
01194                         record_full_resume_step, record_full_resumed,
01195                         record_full_execution_dir == EXEC_FORWARD
01196                         ? "forward" : "reverse");
01197 
01198   if (!record_full_resumed)
01199     {
01200       gdb_assert ((options & TARGET_WNOHANG) != 0);
01201 
01202       /* No interesting event.  */
01203       status->kind = TARGET_WAITKIND_IGNORE;
01204       return minus_one_ptid;
01205     }
01206 
01207   record_full_get_sig = 0;
01208   signal (SIGINT, record_full_sig_handler);
01209 
01210   if (!RECORD_FULL_IS_REPLAY && ops != &record_full_core_ops)
01211     {
01212       if (record_full_resume_step)
01213         {
01214           /* This is a single step.  */
01215           return record_full_beneath_to_wait (record_full_beneath_to_wait_ops,
01216                                               ptid, status, options);
01217         }
01218       else
01219         {
01220           /* This is not a single step.  */
01221           ptid_t ret;
01222           CORE_ADDR tmp_pc;
01223           struct gdbarch *gdbarch = target_thread_architecture (inferior_ptid);
01224 
01225           while (1)
01226             {
01227               ret = record_full_beneath_to_wait
01228                 (record_full_beneath_to_wait_ops, ptid, status, options);
01229               if (status->kind == TARGET_WAITKIND_IGNORE)
01230                 {
01231                   if (record_debug)
01232                     fprintf_unfiltered (gdb_stdlog,
01233                                         "Process record: record_full_wait "
01234                                         "target beneath not done yet\n");
01235                   return ret;
01236                 }
01237 
01238               if (single_step_breakpoints_inserted ())
01239                 remove_single_step_breakpoints ();
01240 
01241               if (record_full_resume_step)
01242                 return ret;
01243 
01244               /* Is this a SIGTRAP?  */
01245               if (status->kind == TARGET_WAITKIND_STOPPED
01246                   && status->value.sig == GDB_SIGNAL_TRAP)
01247                 {
01248                   struct regcache *regcache;
01249                   struct address_space *aspace;
01250 
01251                   /* Yes -- this is likely our single-step finishing,
01252                      but check if there's any reason the core would be
01253                      interested in the event.  */
01254 
01255                   registers_changed ();
01256                   regcache = get_current_regcache ();
01257                   tmp_pc = regcache_read_pc (regcache);
01258                   aspace = get_regcache_aspace (regcache);
01259 
01260                   if (target_stopped_by_watchpoint ())
01261                     {
01262                       /* Always interested in watchpoints.  */
01263                     }
01264                   else if (breakpoint_inserted_here_p (aspace, tmp_pc))
01265                     {
01266                       /* There is a breakpoint here.  Let the core
01267                          handle it.  */
01268                       if (software_breakpoint_inserted_here_p (aspace, tmp_pc))
01269                         {
01270                           struct gdbarch *gdbarch
01271                             = get_regcache_arch (regcache);
01272                           CORE_ADDR decr_pc_after_break
01273                             = gdbarch_decr_pc_after_break (gdbarch);
01274                           if (decr_pc_after_break)
01275                             regcache_write_pc (regcache,
01276                                                tmp_pc + decr_pc_after_break);
01277                         }
01278                     }
01279                   else
01280                     {
01281                       /* This is a single-step trap.  Record the
01282                          insn and issue another step.
01283                          FIXME: this part can be a random SIGTRAP too.
01284                          But GDB cannot handle it.  */
01285                       int step = 1;
01286 
01287                       if (!record_full_message_wrapper_safe (regcache,
01288                                                              GDB_SIGNAL_0))
01289                         {
01290                            status->kind = TARGET_WAITKIND_STOPPED;
01291                            status->value.sig = GDB_SIGNAL_0;
01292                            break;
01293                         }
01294 
01295                       if (gdbarch_software_single_step_p (gdbarch))
01296                         {
01297                           /* Try to insert the software single step breakpoint.
01298                              If insert success, set step to 0.  */
01299                           set_executing (inferior_ptid, 0);
01300                           reinit_frame_cache ();
01301                           if (gdbarch_software_single_step (gdbarch,
01302                                                             get_current_frame ()))
01303                             step = 0;
01304                           set_executing (inferior_ptid, 1);
01305                         }
01306 
01307                       if (record_debug)
01308                         fprintf_unfiltered (gdb_stdlog,
01309                                             "Process record: record_full_wait "
01310                                             "issuing one more step in the "
01311                                             "target beneath\n");
01312                       record_full_beneath_to_resume
01313                         (record_full_beneath_to_resume_ops, ptid, step,
01314                          GDB_SIGNAL_0);
01315                       continue;
01316                     }
01317                 }
01318 
01319               /* The inferior is broken by a breakpoint or a signal.  */
01320               break;
01321             }
01322 
01323           return ret;
01324         }
01325     }
01326   else
01327     {
01328       struct regcache *regcache = get_current_regcache ();
01329       struct gdbarch *gdbarch = get_regcache_arch (regcache);
01330       struct address_space *aspace = get_regcache_aspace (regcache);
01331       int continue_flag = 1;
01332       int first_record_full_end = 1;
01333       struct cleanup *old_cleanups
01334         = make_cleanup (record_full_wait_cleanups, 0);
01335       CORE_ADDR tmp_pc;
01336 
01337       record_full_hw_watchpoint = 0;
01338       status->kind = TARGET_WAITKIND_STOPPED;
01339 
01340       /* Check breakpoint when forward execute.  */
01341       if (execution_direction == EXEC_FORWARD)
01342         {
01343           tmp_pc = regcache_read_pc (regcache);
01344           if (breakpoint_inserted_here_p (aspace, tmp_pc))
01345             {
01346               int decr_pc_after_break = gdbarch_decr_pc_after_break (gdbarch);
01347 
01348               if (record_debug)
01349                 fprintf_unfiltered (gdb_stdlog,
01350                                     "Process record: break at %s.\n",
01351                                     paddress (gdbarch, tmp_pc));
01352 
01353               if (decr_pc_after_break
01354                   && !record_full_resume_step
01355                   && software_breakpoint_inserted_here_p (aspace, tmp_pc))
01356                 regcache_write_pc (regcache,
01357                                    tmp_pc + decr_pc_after_break);
01358               goto replay_out;
01359             }
01360         }
01361 
01362       /* If GDB is in terminal_inferior mode, it will not get the signal.
01363          And in GDB replay mode, GDB doesn't need to be in terminal_inferior
01364          mode, because inferior will not executed.
01365          Then set it to terminal_ours to make GDB get the signal.  */
01366       target_terminal_ours ();
01367 
01368       /* In EXEC_FORWARD mode, record_full_list points to the tail of prev
01369          instruction.  */
01370       if (execution_direction == EXEC_FORWARD && record_full_list->next)
01371         record_full_list = record_full_list->next;
01372 
01373       /* Loop over the record_full_list, looking for the next place to
01374          stop.  */
01375       do
01376         {
01377           /* Check for beginning and end of log.  */
01378           if (execution_direction == EXEC_REVERSE
01379               && record_full_list == &record_full_first)
01380             {
01381               /* Hit beginning of record log in reverse.  */
01382               status->kind = TARGET_WAITKIND_NO_HISTORY;
01383               break;
01384             }
01385           if (execution_direction != EXEC_REVERSE && !record_full_list->next)
01386             {
01387               /* Hit end of record log going forward.  */
01388               status->kind = TARGET_WAITKIND_NO_HISTORY;
01389               break;
01390             }
01391 
01392           record_full_exec_insn (regcache, gdbarch, record_full_list);
01393 
01394           if (record_full_list->type == record_full_end)
01395             {
01396               if (record_debug > 1)
01397                 fprintf_unfiltered (gdb_stdlog,
01398                                     "Process record: record_full_end %s to "
01399                                     "inferior.\n",
01400                                     host_address_to_string (record_full_list));
01401 
01402               if (first_record_full_end && execution_direction == EXEC_REVERSE)
01403                 {
01404                   /* When reverse excute, the first record_full_end is the
01405                      part of current instruction.  */
01406                   first_record_full_end = 0;
01407                 }
01408               else
01409                 {
01410                   /* In EXEC_REVERSE mode, this is the record_full_end of prev
01411                      instruction.
01412                      In EXEC_FORWARD mode, this is the record_full_end of
01413                      current instruction.  */
01414                   /* step */
01415                   if (record_full_resume_step)
01416                     {
01417                       if (record_debug > 1)
01418                         fprintf_unfiltered (gdb_stdlog,
01419                                             "Process record: step.\n");
01420                       continue_flag = 0;
01421                     }
01422 
01423                   /* check breakpoint */
01424                   tmp_pc = regcache_read_pc (regcache);
01425                   if (breakpoint_inserted_here_p (aspace, tmp_pc))
01426                     {
01427                       int decr_pc_after_break
01428                         = gdbarch_decr_pc_after_break (gdbarch);
01429 
01430                       if (record_debug)
01431                         fprintf_unfiltered (gdb_stdlog,
01432                                             "Process record: break "
01433                                             "at %s.\n",
01434                                             paddress (gdbarch, tmp_pc));
01435                       if (decr_pc_after_break
01436                           && execution_direction == EXEC_FORWARD
01437                           && !record_full_resume_step
01438                           && software_breakpoint_inserted_here_p (aspace,
01439                                                                   tmp_pc))
01440                         regcache_write_pc (regcache,
01441                                            tmp_pc + decr_pc_after_break);
01442                       continue_flag = 0;
01443                     }
01444 
01445                   if (record_full_hw_watchpoint)
01446                     {
01447                       if (record_debug)
01448                         fprintf_unfiltered (gdb_stdlog,
01449                                             "Process record: hit hw "
01450                                             "watchpoint.\n");
01451                       continue_flag = 0;
01452                     }
01453                   /* Check target signal */
01454                   if (record_full_list->u.end.sigval != GDB_SIGNAL_0)
01455                     /* FIXME: better way to check */
01456                     continue_flag = 0;
01457                 }
01458             }
01459 
01460           if (continue_flag)
01461             {
01462               if (execution_direction == EXEC_REVERSE)
01463                 {
01464                   if (record_full_list->prev)
01465                     record_full_list = record_full_list->prev;
01466                 }
01467               else
01468                 {
01469                   if (record_full_list->next)
01470                     record_full_list = record_full_list->next;
01471                 }
01472             }
01473         }
01474       while (continue_flag);
01475 
01476 replay_out:
01477       if (record_full_get_sig)
01478         status->value.sig = GDB_SIGNAL_INT;
01479       else if (record_full_list->u.end.sigval != GDB_SIGNAL_0)
01480         /* FIXME: better way to check */
01481         status->value.sig = record_full_list->u.end.sigval;
01482       else
01483         status->value.sig = GDB_SIGNAL_TRAP;
01484 
01485       discard_cleanups (old_cleanups);
01486     }
01487 
01488   signal (SIGINT, handle_sigint);
01489 
01490   do_cleanups (set_cleanups);
01491   return inferior_ptid;
01492 }
01493 
01494 static ptid_t
01495 record_full_wait (struct target_ops *ops,
01496                   ptid_t ptid, struct target_waitstatus *status,
01497                   int options)
01498 {
01499   ptid_t return_ptid;
01500 
01501   return_ptid = record_full_wait_1 (ops, ptid, status, options);
01502   if (status->kind != TARGET_WAITKIND_IGNORE)
01503     {
01504       /* We're reporting a stop.  Make sure any spurious
01505          target_wait(WNOHANG) doesn't advance the target until the
01506          core wants us resumed again.  */
01507       record_full_resumed = 0;
01508     }
01509   return return_ptid;
01510 }
01511 
01512 static int
01513 record_full_stopped_by_watchpoint (void)
01514 {
01515   if (RECORD_FULL_IS_REPLAY)
01516     return record_full_hw_watchpoint;
01517   else
01518     return record_full_beneath_to_stopped_by_watchpoint ();
01519 }
01520 
01521 static int
01522 record_full_stopped_data_address (struct target_ops *ops, CORE_ADDR *addr_p)
01523 {
01524   if (RECORD_FULL_IS_REPLAY)
01525     return 0;
01526   else
01527     return record_full_beneath_to_stopped_data_address (ops, addr_p);
01528 }
01529 
01530 /* Record registers change (by user or by GDB) to list as an instruction.  */
01531 
01532 static void
01533 record_full_registers_change (struct regcache *regcache, int regnum)
01534 {
01535   /* Check record_full_insn_num.  */
01536   record_full_check_insn_num (0);
01537 
01538   record_full_arch_list_head = NULL;
01539   record_full_arch_list_tail = NULL;
01540 
01541   if (regnum < 0)
01542     {
01543       int i;
01544 
01545       for (i = 0; i < gdbarch_num_regs (get_regcache_arch (regcache)); i++)
01546         {
01547           if (record_full_arch_list_add_reg (regcache, i))
01548             {
01549               record_full_list_release (record_full_arch_list_tail);
01550               error (_("Process record: failed to record execution log."));
01551             }
01552         }
01553     }
01554   else
01555     {
01556       if (record_full_arch_list_add_reg (regcache, regnum))
01557         {
01558           record_full_list_release (record_full_arch_list_tail);
01559           error (_("Process record: failed to record execution log."));
01560         }
01561     }
01562   if (record_full_arch_list_add_end ())
01563     {
01564       record_full_list_release (record_full_arch_list_tail);
01565       error (_("Process record: failed to record execution log."));
01566     }
01567   record_full_list->next = record_full_arch_list_head;
01568   record_full_arch_list_head->prev = record_full_list;
01569   record_full_list = record_full_arch_list_tail;
01570 
01571   if (record_full_insn_num == record_full_insn_max_num)
01572     record_full_list_release_first ();
01573   else
01574     record_full_insn_num++;
01575 }
01576 
01577 /* "to_store_registers" method for process record target.  */
01578 
01579 static void
01580 record_full_store_registers (struct target_ops *ops,
01581                              struct regcache *regcache,
01582                              int regno)
01583 {
01584   if (!record_full_gdb_operation_disable)
01585     {
01586       if (RECORD_FULL_IS_REPLAY)
01587         {
01588           int n;
01589 
01590           /* Let user choose if he wants to write register or not.  */
01591           if (regno < 0)
01592             n =
01593               query (_("Because GDB is in replay mode, changing the "
01594                        "value of a register will make the execution "
01595                        "log unusable from this point onward.  "
01596                        "Change all registers?"));
01597           else
01598             n =
01599               query (_("Because GDB is in replay mode, changing the value "
01600                        "of a register will make the execution log unusable "
01601                        "from this point onward.  Change register %s?"),
01602                       gdbarch_register_name (get_regcache_arch (regcache),
01603                                                regno));
01604 
01605           if (!n)
01606             {
01607               /* Invalidate the value of regcache that was set in function
01608                  "regcache_raw_write".  */
01609               if (regno < 0)
01610                 {
01611                   int i;
01612 
01613                   for (i = 0;
01614                        i < gdbarch_num_regs (get_regcache_arch (regcache));
01615                        i++)
01616                     regcache_invalidate (regcache, i);
01617                 }
01618               else
01619                 regcache_invalidate (regcache, regno);
01620 
01621               error (_("Process record canceled the operation."));
01622             }
01623 
01624           /* Destroy the record from here forward.  */
01625           record_full_list_release_following (record_full_list);
01626         }
01627 
01628       record_full_registers_change (regcache, regno);
01629     }
01630   record_full_beneath_to_store_registers
01631     (record_full_beneath_to_store_registers_ops, regcache, regno);
01632 }
01633 
01634 /* "to_xfer_partial" method.  Behavior is conditional on
01635    RECORD_FULL_IS_REPLAY.
01636    In replay mode, we cannot write memory unles we are willing to
01637    invalidate the record/replay log from this point forward.  */
01638 
01639 static LONGEST
01640 record_full_xfer_partial (struct target_ops *ops, enum target_object object,
01641                           const char *annex, gdb_byte *readbuf,
01642                           const gdb_byte *writebuf, ULONGEST offset,
01643                           LONGEST len)
01644 {
01645   if (!record_full_gdb_operation_disable
01646       && (object == TARGET_OBJECT_MEMORY
01647           || object == TARGET_OBJECT_RAW_MEMORY) && writebuf)
01648     {
01649       if (RECORD_FULL_IS_REPLAY)
01650         {
01651           /* Let user choose if he wants to write memory or not.  */
01652           if (!query (_("Because GDB is in replay mode, writing to memory "
01653                         "will make the execution log unusable from this "
01654                         "point onward.  Write memory at address %s?"),
01655                        paddress (target_gdbarch (), offset)))
01656             error (_("Process record canceled the operation."));
01657 
01658           /* Destroy the record from here forward.  */
01659           record_full_list_release_following (record_full_list);
01660         }
01661 
01662       /* Check record_full_insn_num */
01663       record_full_check_insn_num (0);
01664 
01665       /* Record registers change to list as an instruction.  */
01666       record_full_arch_list_head = NULL;
01667       record_full_arch_list_tail = NULL;
01668       if (record_full_arch_list_add_mem (offset, len))
01669         {
01670           record_full_list_release (record_full_arch_list_tail);
01671           if (record_debug)
01672             fprintf_unfiltered (gdb_stdlog,
01673                                 "Process record: failed to record "
01674                                 "execution log.");
01675           return -1;
01676         }
01677       if (record_full_arch_list_add_end ())
01678         {
01679           record_full_list_release (record_full_arch_list_tail);
01680           if (record_debug)
01681             fprintf_unfiltered (gdb_stdlog,
01682                                 "Process record: failed to record "
01683                                 "execution log.");
01684           return -1;
01685         }
01686       record_full_list->next = record_full_arch_list_head;
01687       record_full_arch_list_head->prev = record_full_list;
01688       record_full_list = record_full_arch_list_tail;
01689 
01690       if (record_full_insn_num == record_full_insn_max_num)
01691         record_full_list_release_first ();
01692       else
01693         record_full_insn_num++;
01694     }
01695 
01696   return record_full_beneath_to_xfer_partial
01697     (record_full_beneath_to_xfer_partial_ops, object, annex,
01698      readbuf, writebuf, offset, len);
01699 }
01700 
01701 /* This structure represents a breakpoint inserted while the record
01702    target is active.  We use this to know when to install/remove
01703    breakpoints in/from the target beneath.  For example, a breakpoint
01704    may be inserted while recording, but removed when not replaying nor
01705    recording.  In that case, the breakpoint had not been inserted on
01706    the target beneath, so we should not try to remove it there.  */
01707 
01708 struct record_full_breakpoint
01709 {
01710   /* The address and address space the breakpoint was set at.  */
01711   struct address_space *address_space;
01712   CORE_ADDR addr;
01713 
01714   /* True when the breakpoint has been also installed in the target
01715      beneath.  This will be false for breakpoints set during replay or
01716      when recording.  */
01717   int in_target_beneath;
01718 };
01719 
01720 typedef struct record_full_breakpoint *record_full_breakpoint_p;
01721 DEF_VEC_P(record_full_breakpoint_p);
01722 
01723 /* The list of breakpoints inserted while the record target is
01724    active.  */
01725 VEC(record_full_breakpoint_p) *record_full_breakpoints = NULL;
01726 
01727 static void
01728 record_full_sync_record_breakpoints (struct bp_location *loc, void *data)
01729 {
01730   if (loc->loc_type != bp_loc_software_breakpoint)
01731       return;
01732 
01733   if (loc->inserted)
01734     {
01735       struct record_full_breakpoint *bp = XNEW (struct record_full_breakpoint);
01736 
01737       bp->addr = loc->target_info.placed_address;
01738       bp->address_space = loc->target_info.placed_address_space;
01739 
01740       bp->in_target_beneath = 1;
01741 
01742       VEC_safe_push (record_full_breakpoint_p, record_full_breakpoints, bp);
01743     }
01744 }
01745 
01746 /* Sync existing breakpoints to record_full_breakpoints.  */
01747 
01748 static void
01749 record_full_init_record_breakpoints (void)
01750 {
01751   VEC_free (record_full_breakpoint_p, record_full_breakpoints);
01752 
01753   iterate_over_bp_locations (record_full_sync_record_breakpoints);
01754 }
01755 
01756 /* Behavior is conditional on RECORD_FULL_IS_REPLAY.  We will not actually
01757    insert or remove breakpoints in the real target when replaying, nor
01758    when recording.  */
01759 
01760 static int
01761 record_full_insert_breakpoint (struct gdbarch *gdbarch,
01762                                struct bp_target_info *bp_tgt)
01763 {
01764   struct record_full_breakpoint *bp;
01765   int in_target_beneath = 0;
01766 
01767   if (!RECORD_FULL_IS_REPLAY)
01768     {
01769       /* When recording, we currently always single-step, so we don't
01770          really need to install regular breakpoints in the inferior.
01771          However, we do have to insert software single-step
01772          breakpoints, in case the target can't hardware step.  To keep
01773          things single, we always insert.  */
01774       struct cleanup *old_cleanups;
01775       int ret;
01776 
01777       old_cleanups = record_full_gdb_operation_disable_set ();
01778       ret = record_full_beneath_to_insert_breakpoint (gdbarch, bp_tgt);
01779       do_cleanups (old_cleanups);
01780 
01781       if (ret != 0)
01782         return ret;
01783 
01784       in_target_beneath = 1;
01785     }
01786 
01787   bp = XNEW (struct record_full_breakpoint);
01788   bp->addr = bp_tgt->placed_address;
01789   bp->address_space = bp_tgt->placed_address_space;
01790   bp->in_target_beneath = in_target_beneath;
01791   VEC_safe_push (record_full_breakpoint_p, record_full_breakpoints, bp);
01792   return 0;
01793 }
01794 
01795 /* "to_remove_breakpoint" method for process record target.  */
01796 
01797 static int
01798 record_full_remove_breakpoint (struct gdbarch *gdbarch,
01799                                struct bp_target_info *bp_tgt)
01800 {
01801   struct record_full_breakpoint *bp;
01802   int ix;
01803 
01804   for (ix = 0;
01805        VEC_iterate (record_full_breakpoint_p,
01806                     record_full_breakpoints, ix, bp);
01807        ++ix)
01808     {
01809       if (bp->addr == bp_tgt->placed_address
01810           && bp->address_space == bp_tgt->placed_address_space)
01811         {
01812           if (bp->in_target_beneath)
01813             {
01814               struct cleanup *old_cleanups;
01815               int ret;
01816 
01817               old_cleanups = record_full_gdb_operation_disable_set ();
01818               ret = record_full_beneath_to_remove_breakpoint (gdbarch, bp_tgt);
01819               do_cleanups (old_cleanups);
01820 
01821               if (ret != 0)
01822                 return ret;
01823             }
01824 
01825           VEC_unordered_remove (record_full_breakpoint_p,
01826                                 record_full_breakpoints, ix);
01827           return 0;
01828         }
01829     }
01830 
01831   gdb_assert_not_reached ("removing unknown breakpoint");
01832 }
01833 
01834 /* "to_can_execute_reverse" method for process record target.  */
01835 
01836 static int
01837 record_full_can_execute_reverse (void)
01838 {
01839   return 1;
01840 }
01841 
01842 /* "to_get_bookmark" method for process record and prec over core.  */
01843 
01844 static gdb_byte *
01845 record_full_get_bookmark (char *args, int from_tty)
01846 {
01847   char *ret = NULL;
01848 
01849   /* Return stringified form of instruction count.  */
01850   if (record_full_list && record_full_list->type == record_full_end)
01851     ret = xstrdup (pulongest (record_full_list->u.end.insn_num));
01852 
01853   if (record_debug)
01854     {
01855       if (ret)
01856         fprintf_unfiltered (gdb_stdlog,
01857                             "record_full_get_bookmark returns %s\n", ret);
01858       else
01859         fprintf_unfiltered (gdb_stdlog,
01860                             "record_full_get_bookmark returns NULL\n");
01861     }
01862   return (gdb_byte *) ret;
01863 }
01864 
01865 /* "to_goto_bookmark" method for process record and prec over core.  */
01866 
01867 static void
01868 record_full_goto_bookmark (gdb_byte *raw_bookmark, int from_tty)
01869 {
01870   char *bookmark = (char *) raw_bookmark;
01871 
01872   if (record_debug)
01873     fprintf_unfiltered (gdb_stdlog,
01874                         "record_full_goto_bookmark receives %s\n", bookmark);
01875 
01876   if (bookmark[0] == '\'' || bookmark[0] == '\"')
01877     {
01878       if (bookmark[strlen (bookmark) - 1] != bookmark[0])
01879         error (_("Unbalanced quotes: %s"), bookmark);
01880 
01881       /* Strip trailing quote.  */
01882       bookmark[strlen (bookmark) - 1] = '\0';
01883       /* Strip leading quote.  */
01884       bookmark++;
01885       /* Pass along to cmd_record_full_goto.  */
01886     }
01887 
01888   cmd_record_goto (bookmark, from_tty);
01889   return;
01890 }
01891 
01892 static void
01893 record_full_async (void (*callback) (enum inferior_event_type event_type,
01894                                      void *context), void *context)
01895 {
01896   /* If we're on top of a line target (e.g., linux-nat, remote), then
01897      set it to async mode as well.  Will be NULL if we're sitting on
01898      top of the core target, for "record restore".  */
01899   if (record_full_beneath_to_async != NULL)
01900     record_full_beneath_to_async (callback, context);
01901 }
01902 
01903 static int
01904 record_full_can_async_p (void)
01905 {
01906   /* We only enable async when the user specifically asks for it.  */
01907   return target_async_permitted;
01908 }
01909 
01910 static int
01911 record_full_is_async_p (void)
01912 {
01913   /* We only enable async when the user specifically asks for it.  */
01914   return target_async_permitted;
01915 }
01916 
01917 static enum exec_direction_kind
01918 record_full_execution_direction (void)
01919 {
01920   return record_full_execution_dir;
01921 }
01922 
01923 static void
01924 record_full_info (void)
01925 {
01926   struct record_full_entry *p;
01927 
01928   if (RECORD_FULL_IS_REPLAY)
01929     printf_filtered (_("Replay mode:\n"));
01930   else
01931     printf_filtered (_("Record mode:\n"));
01932 
01933   /* Find entry for first actual instruction in the log.  */
01934   for (p = record_full_first.next;
01935        p != NULL && p->type != record_full_end;
01936        p = p->next)
01937     ;
01938 
01939   /* Do we have a log at all?  */
01940   if (p != NULL && p->type == record_full_end)
01941     {
01942       /* Display instruction number for first instruction in the log.  */
01943       printf_filtered (_("Lowest recorded instruction number is %s.\n"),
01944                        pulongest (p->u.end.insn_num));
01945 
01946       /* If in replay mode, display where we are in the log.  */
01947       if (RECORD_FULL_IS_REPLAY)
01948         printf_filtered (_("Current instruction number is %s.\n"),
01949                          pulongest (record_full_list->u.end.insn_num));
01950 
01951       /* Display instruction number for last instruction in the log.  */
01952       printf_filtered (_("Highest recorded instruction number is %s.\n"),
01953                        pulongest (record_full_insn_count));
01954 
01955       /* Display log count.  */
01956       printf_filtered (_("Log contains %u instructions.\n"),
01957                        record_full_insn_num);
01958     }
01959   else
01960     printf_filtered (_("No instructions have been logged.\n"));
01961 
01962   /* Display max log size.  */
01963   printf_filtered (_("Max logged instructions is %u.\n"),
01964                    record_full_insn_max_num);
01965 }
01966 
01967 /* The "to_record_delete" target method.  */
01968 
01969 static void
01970 record_full_delete (void)
01971 {
01972   record_full_list_release_following (record_full_list);
01973 }
01974 
01975 /* The "to_record_is_replaying" target method.  */
01976 
01977 static int
01978 record_full_is_replaying (void)
01979 {
01980   return RECORD_FULL_IS_REPLAY;
01981 }
01982 
01983 /* Go to a specific entry.  */
01984 
01985 static void
01986 record_full_goto_entry (struct record_full_entry *p)
01987 {
01988   if (p == NULL)
01989     error (_("Target insn not found."));
01990   else if (p == record_full_list)
01991     error (_("Already at target insn."));
01992   else if (p->u.end.insn_num > record_full_list->u.end.insn_num)
01993     {
01994       printf_filtered (_("Go forward to insn number %s\n"),
01995                        pulongest (p->u.end.insn_num));
01996       record_full_goto_insn (p, EXEC_FORWARD);
01997     }
01998   else
01999     {
02000       printf_filtered (_("Go backward to insn number %s\n"),
02001                        pulongest (p->u.end.insn_num));
02002       record_full_goto_insn (p, EXEC_REVERSE);
02003     }
02004 
02005   registers_changed ();
02006   reinit_frame_cache ();
02007   print_stack_frame (get_selected_frame (NULL), 1, SRC_AND_LOC, 1);
02008 }
02009 
02010 /* The "to_goto_record_begin" target method.  */
02011 
02012 static void
02013 record_full_goto_begin (void)
02014 {
02015   struct record_full_entry *p = NULL;
02016 
02017   for (p = &record_full_first; p != NULL; p = p->next)
02018     if (p->type == record_full_end)
02019       break;
02020 
02021   record_full_goto_entry (p);
02022 }
02023 
02024 /* The "to_goto_record_end" target method.  */
02025 
02026 static void
02027 record_full_goto_end (void)
02028 {
02029   struct record_full_entry *p = NULL;
02030 
02031   for (p = record_full_list; p->next != NULL; p = p->next)
02032     ;
02033   for (; p!= NULL; p = p->prev)
02034     if (p->type == record_full_end)
02035       break;
02036 
02037   record_full_goto_entry (p);
02038 }
02039 
02040 /* The "to_goto_record" target method.  */
02041 
02042 static void
02043 record_full_goto (ULONGEST target_insn)
02044 {
02045   struct record_full_entry *p = NULL;
02046 
02047   for (p = &record_full_first; p != NULL; p = p->next)
02048     if (p->type == record_full_end && p->u.end.insn_num == target_insn)
02049       break;
02050 
02051   record_full_goto_entry (p);
02052 }
02053 
02054 static void
02055 init_record_full_ops (void)
02056 {
02057   record_full_ops.to_shortname = "record-full";
02058   record_full_ops.to_longname = "Process record and replay target";
02059   record_full_ops.to_doc =
02060     "Log program while executing and replay execution from log.";
02061   record_full_ops.to_open = record_full_open;
02062   record_full_ops.to_close = record_full_close;
02063   record_full_ops.to_resume = record_full_resume;
02064   record_full_ops.to_wait = record_full_wait;
02065   record_full_ops.to_disconnect = record_disconnect;
02066   record_full_ops.to_detach = record_detach;
02067   record_full_ops.to_mourn_inferior = record_mourn_inferior;
02068   record_full_ops.to_kill = record_kill;
02069   record_full_ops.to_create_inferior = find_default_create_inferior;
02070   record_full_ops.to_store_registers = record_full_store_registers;
02071   record_full_ops.to_xfer_partial = record_full_xfer_partial;
02072   record_full_ops.to_insert_breakpoint = record_full_insert_breakpoint;
02073   record_full_ops.to_remove_breakpoint = record_full_remove_breakpoint;
02074   record_full_ops.to_stopped_by_watchpoint = record_full_stopped_by_watchpoint;
02075   record_full_ops.to_stopped_data_address = record_full_stopped_data_address;
02076   record_full_ops.to_can_execute_reverse = record_full_can_execute_reverse;
02077   record_full_ops.to_stratum = record_stratum;
02078   /* Add bookmark target methods.  */
02079   record_full_ops.to_get_bookmark = record_full_get_bookmark;
02080   record_full_ops.to_goto_bookmark = record_full_goto_bookmark;
02081   record_full_ops.to_async = record_full_async;
02082   record_full_ops.to_can_async_p = record_full_can_async_p;
02083   record_full_ops.to_is_async_p = record_full_is_async_p;
02084   record_full_ops.to_execution_direction = record_full_execution_direction;
02085   record_full_ops.to_info_record = record_full_info;
02086   record_full_ops.to_save_record = record_full_save;
02087   record_full_ops.to_delete_record = record_full_delete;
02088   record_full_ops.to_record_is_replaying = record_full_is_replaying;
02089   record_full_ops.to_goto_record_begin = record_full_goto_begin;
02090   record_full_ops.to_goto_record_end = record_full_goto_end;
02091   record_full_ops.to_goto_record = record_full_goto;
02092   record_full_ops.to_magic = OPS_MAGIC;
02093 }
02094 
02095 /* "to_resume" method for prec over corefile.  */
02096 
02097 static void
02098 record_full_core_resume (struct target_ops *ops, ptid_t ptid, int step,
02099                          enum gdb_signal signal)
02100 {
02101   record_full_resume_step = step;
02102   record_full_resumed = 1;
02103   record_full_execution_dir = execution_direction;
02104 
02105   /* We are about to start executing the inferior (or simulate it),
02106      let's register it with the event loop.  */
02107   if (target_can_async_p ())
02108     {
02109       target_async (inferior_event_handler, 0);
02110 
02111       /* Notify the event loop there's an event to wait for.  */
02112       mark_async_event_handler (record_full_async_inferior_event_token);
02113     }
02114 }
02115 
02116 /* "to_kill" method for prec over corefile.  */
02117 
02118 static void
02119 record_full_core_kill (struct target_ops *ops)
02120 {
02121   if (record_debug)
02122     fprintf_unfiltered (gdb_stdlog, "Process record: record_full_core_kill\n");
02123 
02124   unpush_target (&record_full_core_ops);
02125 }
02126 
02127 /* "to_fetch_registers" method for prec over corefile.  */
02128 
02129 static void
02130 record_full_core_fetch_registers (struct target_ops *ops,
02131                                   struct regcache *regcache,
02132                                   int regno)
02133 {
02134   if (regno < 0)
02135     {
02136       int num = gdbarch_num_regs (get_regcache_arch (regcache));
02137       int i;
02138 
02139       for (i = 0; i < num; i ++)
02140         regcache_raw_supply (regcache, i,
02141                              record_full_core_regbuf + MAX_REGISTER_SIZE * i);
02142     }
02143   else
02144     regcache_raw_supply (regcache, regno,
02145                          record_full_core_regbuf + MAX_REGISTER_SIZE * regno);
02146 }
02147 
02148 /* "to_prepare_to_store" method for prec over corefile.  */
02149 
02150 static void
02151 record_full_core_prepare_to_store (struct regcache *regcache)
02152 {
02153 }
02154 
02155 /* "to_store_registers" method for prec over corefile.  */
02156 
02157 static void
02158 record_full_core_store_registers (struct target_ops *ops,
02159                              struct regcache *regcache,
02160                              int regno)
02161 {
02162   if (record_full_gdb_operation_disable)
02163     regcache_raw_collect (regcache, regno,
02164                           record_full_core_regbuf + MAX_REGISTER_SIZE * regno);
02165   else
02166     error (_("You can't do that without a process to debug."));
02167 }
02168 
02169 /* "to_xfer_partial" method for prec over corefile.  */
02170 
02171 static LONGEST
02172 record_full_core_xfer_partial (struct target_ops *ops,
02173                                enum target_object object,
02174                                const char *annex, gdb_byte *readbuf,
02175                                const gdb_byte *writebuf, ULONGEST offset,
02176                                LONGEST len)
02177 {
02178   if (object == TARGET_OBJECT_MEMORY)
02179     {
02180       if (record_full_gdb_operation_disable || !writebuf)
02181         {
02182           struct target_section *p;
02183 
02184           for (p = record_full_core_start; p < record_full_core_end; p++)
02185             {
02186               if (offset >= p->addr)
02187                 {
02188                   struct record_full_core_buf_entry *entry;
02189                   ULONGEST sec_offset;
02190 
02191                   if (offset >= p->endaddr)
02192                     continue;
02193 
02194                   if (offset + len > p->endaddr)
02195                     len = p->endaddr - offset;
02196 
02197                   sec_offset = offset - p->addr;
02198 
02199                   /* Read readbuf or write writebuf p, offset, len.  */
02200                   /* Check flags.  */
02201                   if (p->the_bfd_section->flags & SEC_CONSTRUCTOR
02202                       || (p->the_bfd_section->flags & SEC_HAS_CONTENTS) == 0)
02203                     {
02204                       if (readbuf)
02205                         memset (readbuf, 0, len);
02206                       return len;
02207                     }
02208                   /* Get record_full_core_buf_entry.  */
02209                   for (entry = record_full_core_buf_list; entry;
02210                        entry = entry->prev)
02211                     if (entry->p == p)
02212                       break;
02213                   if (writebuf)
02214                     {
02215                       if (!entry)
02216                         {
02217                           /* Add a new entry.  */
02218                           entry = (struct record_full_core_buf_entry *)
02219                             xmalloc
02220                             (sizeof (struct record_full_core_buf_entry));
02221                           entry->p = p;
02222                           if (!bfd_malloc_and_get_section
02223                                 (p->the_bfd_section->owner,
02224                                  p->the_bfd_section,
02225                                  &entry->buf))
02226                             {
02227                               xfree (entry);
02228                               return 0;
02229                             }
02230                           entry->prev = record_full_core_buf_list;
02231                           record_full_core_buf_list = entry;
02232                         }
02233 
02234                       memcpy (entry->buf + sec_offset, writebuf,
02235                               (size_t) len);
02236                     }
02237                   else
02238                     {
02239                       if (!entry)
02240                         return record_full_beneath_to_xfer_partial
02241                           (record_full_beneath_to_xfer_partial_ops,
02242                            object, annex, readbuf, writebuf,
02243                            offset, len);
02244 
02245                       memcpy (readbuf, entry->buf + sec_offset,
02246                               (size_t) len);
02247                     }
02248 
02249                   return len;
02250                 }
02251             }
02252 
02253           return -1;
02254         }
02255       else
02256         error (_("You can't do that without a process to debug."));
02257     }
02258 
02259   return record_full_beneath_to_xfer_partial
02260     (record_full_beneath_to_xfer_partial_ops, object, annex,
02261      readbuf, writebuf, offset, len);
02262 }
02263 
02264 /* "to_insert_breakpoint" method for prec over corefile.  */
02265 
02266 static int
02267 record_full_core_insert_breakpoint (struct gdbarch *gdbarch,
02268                                     struct bp_target_info *bp_tgt)
02269 {
02270   return 0;
02271 }
02272 
02273 /* "to_remove_breakpoint" method for prec over corefile.  */
02274 
02275 static int
02276 record_full_core_remove_breakpoint (struct gdbarch *gdbarch,
02277                                     struct bp_target_info *bp_tgt)
02278 {
02279   return 0;
02280 }
02281 
02282 /* "to_has_execution" method for prec over corefile.  */
02283 
02284 static int
02285 record_full_core_has_execution (struct target_ops *ops, ptid_t the_ptid)
02286 {
02287   return 1;
02288 }
02289 
02290 static void
02291 init_record_full_core_ops (void)
02292 {
02293   record_full_core_ops.to_shortname = "record-core";
02294   record_full_core_ops.to_longname = "Process record and replay target";
02295   record_full_core_ops.to_doc =
02296     "Log program while executing and replay execution from log.";
02297   record_full_core_ops.to_open = record_full_open;
02298   record_full_core_ops.to_close = record_full_close;
02299   record_full_core_ops.to_resume = record_full_core_resume;
02300   record_full_core_ops.to_wait = record_full_wait;
02301   record_full_core_ops.to_kill = record_full_core_kill;
02302   record_full_core_ops.to_fetch_registers = record_full_core_fetch_registers;
02303   record_full_core_ops.to_prepare_to_store = record_full_core_prepare_to_store;
02304   record_full_core_ops.to_store_registers = record_full_core_store_registers;
02305   record_full_core_ops.to_xfer_partial = record_full_core_xfer_partial;
02306   record_full_core_ops.to_insert_breakpoint
02307     = record_full_core_insert_breakpoint;
02308   record_full_core_ops.to_remove_breakpoint
02309     = record_full_core_remove_breakpoint;
02310   record_full_core_ops.to_stopped_by_watchpoint
02311     = record_full_stopped_by_watchpoint;
02312   record_full_core_ops.to_stopped_data_address
02313     = record_full_stopped_data_address;
02314   record_full_core_ops.to_can_execute_reverse
02315     = record_full_can_execute_reverse;
02316   record_full_core_ops.to_has_execution = record_full_core_has_execution;
02317   record_full_core_ops.to_stratum = record_stratum;
02318   /* Add bookmark target methods.  */
02319   record_full_core_ops.to_get_bookmark = record_full_get_bookmark;
02320   record_full_core_ops.to_goto_bookmark = record_full_goto_bookmark;
02321   record_full_core_ops.to_async = record_full_async;
02322   record_full_core_ops.to_can_async_p = record_full_can_async_p;
02323   record_full_core_ops.to_is_async_p = record_full_is_async_p;
02324   record_full_core_ops.to_execution_direction
02325     = record_full_execution_direction;
02326   record_full_core_ops.to_info_record = record_full_info;
02327   record_full_core_ops.to_delete_record = record_full_delete;
02328   record_full_core_ops.to_record_is_replaying = record_full_is_replaying;
02329   record_full_core_ops.to_goto_record_begin = record_full_goto_begin;
02330   record_full_core_ops.to_goto_record_end = record_full_goto_end;
02331   record_full_core_ops.to_goto_record = record_full_goto;
02332   record_full_core_ops.to_magic = OPS_MAGIC;
02333 }
02334 
02335 /* Record log save-file format
02336    Version 1 (never released)
02337 
02338    Header:
02339      4 bytes: magic number htonl(0x20090829).
02340        NOTE: be sure to change whenever this file format changes!
02341 
02342    Records:
02343      record_full_end:
02344        1 byte:  record type (record_full_end, see enum record_full_type).
02345      record_full_reg:
02346        1 byte:  record type (record_full_reg, see enum record_full_type).
02347        8 bytes: register id (network byte order).
02348        MAX_REGISTER_SIZE bytes: register value.
02349      record_full_mem:
02350        1 byte:  record type (record_full_mem, see enum record_full_type).
02351        8 bytes: memory length (network byte order).
02352        8 bytes: memory address (network byte order).
02353        n bytes: memory value (n == memory length).
02354 
02355    Version 2
02356      4 bytes: magic number netorder32(0x20091016).
02357        NOTE: be sure to change whenever this file format changes!
02358 
02359    Records:
02360      record_full_end:
02361        1 byte:  record type (record_full_end, see enum record_full_type).
02362        4 bytes: signal
02363        4 bytes: instruction count
02364      record_full_reg:
02365        1 byte:  record type (record_full_reg, see enum record_full_type).
02366        4 bytes: register id (network byte order).
02367        n bytes: register value (n == actual register size).
02368                 (eg. 4 bytes for x86 general registers).
02369      record_full_mem:
02370        1 byte:  record type (record_full_mem, see enum record_full_type).
02371        4 bytes: memory length (network byte order).
02372        8 bytes: memory address (network byte order).
02373        n bytes: memory value (n == memory length).
02374 
02375 */
02376 
02377 /* bfdcore_read -- read bytes from a core file section.  */
02378 
02379 static inline void
02380 bfdcore_read (bfd *obfd, asection *osec, void *buf, int len, int *offset)
02381 {
02382   int ret = bfd_get_section_contents (obfd, osec, buf, *offset, len);
02383 
02384   if (ret)
02385     *offset += len;
02386   else
02387     error (_("Failed to read %d bytes from core file %s ('%s')."),
02388            len, bfd_get_filename (obfd),
02389            bfd_errmsg (bfd_get_error ()));
02390 }
02391 
02392 static inline uint64_t
02393 netorder64 (uint64_t input)
02394 {
02395   uint64_t ret;
02396 
02397   store_unsigned_integer ((gdb_byte *) &ret, sizeof (ret), 
02398                           BFD_ENDIAN_BIG, input);
02399   return ret;
02400 }
02401 
02402 static inline uint32_t
02403 netorder32 (uint32_t input)
02404 {
02405   uint32_t ret;
02406 
02407   store_unsigned_integer ((gdb_byte *) &ret, sizeof (ret), 
02408                           BFD_ENDIAN_BIG, input);
02409   return ret;
02410 }
02411 
02412 static inline uint16_t
02413 netorder16 (uint16_t input)
02414 {
02415   uint16_t ret;
02416 
02417   store_unsigned_integer ((gdb_byte *) &ret, sizeof (ret), 
02418                           BFD_ENDIAN_BIG, input);
02419   return ret;
02420 }
02421 
02422 /* Restore the execution log from a core_bfd file.  */
02423 static void
02424 record_full_restore (void)
02425 {
02426   uint32_t magic;
02427   struct cleanup *old_cleanups;
02428   struct record_full_entry *rec;
02429   asection *osec;
02430   uint32_t osec_size;
02431   int bfd_offset = 0;
02432   struct regcache *regcache;
02433 
02434   /* We restore the execution log from the open core bfd,
02435      if there is one.  */
02436   if (core_bfd == NULL)
02437     return;
02438 
02439   /* "record_full_restore" can only be called when record list is empty.  */
02440   gdb_assert (record_full_first.next == NULL);
02441  
02442   if (record_debug)
02443     fprintf_unfiltered (gdb_stdlog, "Restoring recording from core file.\n");
02444 
02445   /* Now need to find our special note section.  */
02446   osec = bfd_get_section_by_name (core_bfd, "null0");
02447   if (record_debug)
02448     fprintf_unfiltered (gdb_stdlog, "Find precord section %s.\n",
02449                         osec ? "succeeded" : "failed");
02450   if (osec == NULL)
02451     return;
02452   osec_size = bfd_section_size (core_bfd, osec);
02453   if (record_debug)
02454     fprintf_unfiltered (gdb_stdlog, "%s", bfd_section_name (core_bfd, osec));
02455 
02456   /* Check the magic code.  */
02457   bfdcore_read (core_bfd, osec, &magic, sizeof (magic), &bfd_offset);
02458   if (magic != RECORD_FULL_FILE_MAGIC)
02459     error (_("Version mis-match or file format error in core file %s."),
02460            bfd_get_filename (core_bfd));
02461   if (record_debug)
02462     fprintf_unfiltered (gdb_stdlog,
02463                         "  Reading 4-byte magic cookie "
02464                         "RECORD_FULL_FILE_MAGIC (0x%s)\n",
02465                         phex_nz (netorder32 (magic), 4));
02466 
02467   /* Restore the entries in recfd into record_full_arch_list_head and
02468      record_full_arch_list_tail.  */
02469   record_full_arch_list_head = NULL;
02470   record_full_arch_list_tail = NULL;
02471   record_full_insn_num = 0;
02472   old_cleanups = make_cleanup (record_full_arch_list_cleanups, 0);
02473   regcache = get_current_regcache ();
02474 
02475   while (1)
02476     {
02477       uint8_t rectype;
02478       uint32_t regnum, len, signal, count;
02479       uint64_t addr;
02480 
02481       /* We are finished when offset reaches osec_size.  */
02482       if (bfd_offset >= osec_size)
02483         break;
02484       bfdcore_read (core_bfd, osec, &rectype, sizeof (rectype), &bfd_offset);
02485 
02486       switch (rectype)
02487         {
02488         case record_full_reg: /* reg */
02489           /* Get register number to regnum.  */
02490           bfdcore_read (core_bfd, osec, &regnum,
02491                         sizeof (regnum), &bfd_offset);
02492           regnum = netorder32 (regnum);
02493 
02494           rec = record_full_reg_alloc (regcache, regnum);
02495 
02496           /* Get val.  */
02497           bfdcore_read (core_bfd, osec, record_full_get_loc (rec),
02498                         rec->u.reg.len, &bfd_offset);
02499 
02500           if (record_debug)
02501             fprintf_unfiltered (gdb_stdlog,
02502                                 "  Reading register %d (1 "
02503                                 "plus %lu plus %d bytes)\n",
02504                                 rec->u.reg.num,
02505                                 (unsigned long) sizeof (regnum),
02506                                 rec->u.reg.len);
02507           break;
02508 
02509         case record_full_mem: /* mem */
02510           /* Get len.  */
02511           bfdcore_read (core_bfd, osec, &len, 
02512                         sizeof (len), &bfd_offset);
02513           len = netorder32 (len);
02514 
02515           /* Get addr.  */
02516           bfdcore_read (core_bfd, osec, &addr,
02517                         sizeof (addr), &bfd_offset);
02518           addr = netorder64 (addr);
02519 
02520           rec = record_full_mem_alloc (addr, len);
02521 
02522           /* Get val.  */
02523           bfdcore_read (core_bfd, osec, record_full_get_loc (rec),
02524                         rec->u.mem.len, &bfd_offset);
02525 
02526           if (record_debug)
02527             fprintf_unfiltered (gdb_stdlog,
02528                                 "  Reading memory %s (1 plus "
02529                                 "%lu plus %lu plus %d bytes)\n",
02530                                 paddress (get_current_arch (),
02531                                           rec->u.mem.addr),
02532                                 (unsigned long) sizeof (addr),
02533                                 (unsigned long) sizeof (len),
02534                                 rec->u.mem.len);
02535           break;
02536 
02537         case record_full_end: /* end */
02538           rec = record_full_end_alloc ();
02539           record_full_insn_num ++;
02540 
02541           /* Get signal value.  */
02542           bfdcore_read (core_bfd, osec, &signal, 
02543                         sizeof (signal), &bfd_offset);
02544           signal = netorder32 (signal);
02545           rec->u.end.sigval = signal;
02546 
02547           /* Get insn count.  */
02548           bfdcore_read (core_bfd, osec, &count, 
02549                         sizeof (count), &bfd_offset);
02550           count = netorder32 (count);
02551           rec->u.end.insn_num = count;
02552           record_full_insn_count = count + 1;
02553           if (record_debug)
02554             fprintf_unfiltered (gdb_stdlog,
02555                                 "  Reading record_full_end (1 + "
02556                                 "%lu + %lu bytes), offset == %s\n",
02557                                 (unsigned long) sizeof (signal),
02558                                 (unsigned long) sizeof (count),
02559                                 paddress (get_current_arch (),
02560                                           bfd_offset));
02561           break;
02562 
02563         default:
02564           error (_("Bad entry type in core file %s."),
02565                  bfd_get_filename (core_bfd));
02566           break;
02567         }
02568 
02569       /* Add rec to record arch list.  */
02570       record_full_arch_list_add (rec);
02571     }
02572 
02573   discard_cleanups (old_cleanups);
02574 
02575   /* Add record_full_arch_list_head to the end of record list.  */
02576   record_full_first.next = record_full_arch_list_head;
02577   record_full_arch_list_head->prev = &record_full_first;
02578   record_full_arch_list_tail->next = NULL;
02579   record_full_list = &record_full_first;
02580 
02581   /* Update record_full_insn_max_num.  */
02582   if (record_full_insn_num > record_full_insn_max_num)
02583     {
02584       record_full_insn_max_num = record_full_insn_num;
02585       warning (_("Auto increase record/replay buffer limit to %u."),
02586                record_full_insn_max_num);
02587     }
02588 
02589   /* Succeeded.  */
02590   printf_filtered (_("Restored records from core file %s.\n"),
02591                    bfd_get_filename (core_bfd));
02592 
02593   print_stack_frame (get_selected_frame (NULL), 1, SRC_AND_LOC, 1);
02594 }
02595 
02596 /* bfdcore_write -- write bytes into a core file section.  */
02597 
02598 static inline void
02599 bfdcore_write (bfd *obfd, asection *osec, void *buf, int len, int *offset)
02600 {
02601   int ret = bfd_set_section_contents (obfd, osec, buf, *offset, len);
02602 
02603   if (ret)
02604     *offset += len;
02605   else
02606     error (_("Failed to write %d bytes to core file %s ('%s')."),
02607            len, bfd_get_filename (obfd),
02608            bfd_errmsg (bfd_get_error ()));
02609 }
02610 
02611 /* Restore the execution log from a file.  We use a modified elf
02612    corefile format, with an extra section for our data.  */
02613 
02614 static void
02615 cmd_record_full_restore (char *args, int from_tty)
02616 {
02617   core_file_command (args, from_tty);
02618   record_full_open (args, from_tty);
02619 }
02620 
02621 static void
02622 record_full_save_cleanups (void *data)
02623 {
02624   bfd *obfd = data;
02625   char *pathname = xstrdup (bfd_get_filename (obfd));
02626 
02627   gdb_bfd_unref (obfd);
02628   unlink (pathname);
02629   xfree (pathname);
02630 }
02631 
02632 /* Save the execution log to a file.  We use a modified elf corefile
02633    format, with an extra section for our data.  */
02634 
02635 static void
02636 record_full_save (const char *recfilename)
02637 {
02638   struct record_full_entry *cur_record_full_list;
02639   uint32_t magic;
02640   struct regcache *regcache;
02641   struct gdbarch *gdbarch;
02642   struct cleanup *old_cleanups;
02643   struct cleanup *set_cleanups;
02644   bfd *obfd;
02645   int save_size = 0;
02646   asection *osec = NULL;
02647   int bfd_offset = 0;
02648 
02649   /* Open the save file.  */
02650   if (record_debug)
02651     fprintf_unfiltered (gdb_stdlog, "Saving execution log to core file '%s'\n",
02652                         recfilename);
02653 
02654   /* Open the output file.  */
02655   obfd = create_gcore_bfd (recfilename);
02656   old_cleanups = make_cleanup (record_full_save_cleanups, obfd);
02657 
02658   /* Save the current record entry to "cur_record_full_list".  */
02659   cur_record_full_list = record_full_list;
02660 
02661   /* Get the values of regcache and gdbarch.  */
02662   regcache = get_current_regcache ();
02663   gdbarch = get_regcache_arch (regcache);
02664 
02665   /* Disable the GDB operation record.  */
02666   set_cleanups = record_full_gdb_operation_disable_set ();
02667 
02668   /* Reverse execute to the begin of record list.  */
02669   while (1)
02670     {
02671       /* Check for beginning and end of log.  */
02672       if (record_full_list == &record_full_first)
02673         break;
02674 
02675       record_full_exec_insn (regcache, gdbarch, record_full_list);
02676 
02677       if (record_full_list->prev)
02678         record_full_list = record_full_list->prev;
02679     }
02680 
02681   /* Compute the size needed for the extra bfd section.  */
02682   save_size = 4;        /* magic cookie */
02683   for (record_full_list = record_full_first.next; record_full_list;
02684        record_full_list = record_full_list->next)
02685     switch (record_full_list->type)
02686       {
02687       case record_full_end:
02688         save_size += 1 + 4 + 4;
02689         break;
02690       case record_full_reg:
02691         save_size += 1 + 4 + record_full_list->u.reg.len;
02692         break;
02693       case record_full_mem:
02694         save_size += 1 + 4 + 8 + record_full_list->u.mem.len;
02695         break;
02696       }
02697 
02698   /* Make the new bfd section.  */
02699   osec = bfd_make_section_anyway_with_flags (obfd, "precord",
02700                                              SEC_HAS_CONTENTS
02701                                              | SEC_READONLY);
02702   if (osec == NULL)
02703     error (_("Failed to create 'precord' section for corefile %s: %s"),
02704            recfilename,
02705            bfd_errmsg (bfd_get_error ()));
02706   bfd_set_section_size (obfd, osec, save_size);
02707   bfd_set_section_vma (obfd, osec, 0);
02708   bfd_set_section_alignment (obfd, osec, 0);
02709   bfd_section_lma (obfd, osec) = 0;
02710 
02711   /* Save corefile state.  */
02712   write_gcore_file (obfd);
02713 
02714   /* Write out the record log.  */
02715   /* Write the magic code.  */
02716   magic = RECORD_FULL_FILE_MAGIC;
02717   if (record_debug)
02718     fprintf_unfiltered (gdb_stdlog,
02719                         "  Writing 4-byte magic cookie "
02720                         "RECORD_FULL_FILE_MAGIC (0x%s)\n",
02721                       phex_nz (magic, 4));
02722   bfdcore_write (obfd, osec, &magic, sizeof (magic), &bfd_offset);
02723 
02724   /* Save the entries to recfd and forward execute to the end of
02725      record list.  */
02726   record_full_list = &record_full_first;
02727   while (1)
02728     {
02729       /* Save entry.  */
02730       if (record_full_list != &record_full_first)
02731         {
02732           uint8_t type;
02733           uint32_t regnum, len, signal, count;
02734           uint64_t addr;
02735 
02736           type = record_full_list->type;
02737           bfdcore_write (obfd, osec, &type, sizeof (type), &bfd_offset);
02738 
02739           switch (record_full_list->type)
02740             {
02741             case record_full_reg: /* reg */
02742               if (record_debug)
02743                 fprintf_unfiltered (gdb_stdlog,
02744                                     "  Writing register %d (1 "
02745                                     "plus %lu plus %d bytes)\n",
02746                                     record_full_list->u.reg.num,
02747                                     (unsigned long) sizeof (regnum),
02748                                     record_full_list->u.reg.len);
02749 
02750               /* Write regnum.  */
02751               regnum = netorder32 (record_full_list->u.reg.num);
02752               bfdcore_write (obfd, osec, &regnum,
02753                              sizeof (regnum), &bfd_offset);
02754 
02755               /* Write regval.  */
02756               bfdcore_write (obfd, osec,
02757                              record_full_get_loc (record_full_list),
02758                              record_full_list->u.reg.len, &bfd_offset);
02759               break;
02760 
02761             case record_full_mem: /* mem */
02762               if (record_debug)
02763                 fprintf_unfiltered (gdb_stdlog,
02764                                     "  Writing memory %s (1 plus "
02765                                     "%lu plus %lu plus %d bytes)\n",
02766                                     paddress (gdbarch,
02767                                               record_full_list->u.mem.addr),
02768                                     (unsigned long) sizeof (addr),
02769                                     (unsigned long) sizeof (len),
02770                                     record_full_list->u.mem.len);
02771 
02772               /* Write memlen.  */
02773               len = netorder32 (record_full_list->u.mem.len);
02774               bfdcore_write (obfd, osec, &len, sizeof (len), &bfd_offset);
02775 
02776               /* Write memaddr.  */
02777               addr = netorder64 (record_full_list->u.mem.addr);
02778               bfdcore_write (obfd, osec, &addr, 
02779                              sizeof (addr), &bfd_offset);
02780 
02781               /* Write memval.  */
02782               bfdcore_write (obfd, osec,
02783                              record_full_get_loc (record_full_list),
02784                              record_full_list->u.mem.len, &bfd_offset);
02785               break;
02786 
02787               case record_full_end:
02788                 if (record_debug)
02789                   fprintf_unfiltered (gdb_stdlog,
02790                                       "  Writing record_full_end (1 + "
02791                                       "%lu + %lu bytes)\n", 
02792                                       (unsigned long) sizeof (signal),
02793                                       (unsigned long) sizeof (count));
02794                 /* Write signal value.  */
02795                 signal = netorder32 (record_full_list->u.end.sigval);
02796                 bfdcore_write (obfd, osec, &signal,
02797                                sizeof (signal), &bfd_offset);
02798 
02799                 /* Write insn count.  */
02800                 count = netorder32 (record_full_list->u.end.insn_num);
02801                 bfdcore_write (obfd, osec, &count,
02802                                sizeof (count), &bfd_offset);
02803                 break;
02804             }
02805         }
02806 
02807       /* Execute entry.  */
02808       record_full_exec_insn (regcache, gdbarch, record_full_list);
02809 
02810       if (record_full_list->next)
02811         record_full_list = record_full_list->next;
02812       else
02813         break;
02814     }
02815 
02816   /* Reverse execute to cur_record_full_list.  */
02817   while (1)
02818     {
02819       /* Check for beginning and end of log.  */
02820       if (record_full_list == cur_record_full_list)
02821         break;
02822 
02823       record_full_exec_insn (regcache, gdbarch, record_full_list);
02824 
02825       if (record_full_list->prev)
02826         record_full_list = record_full_list->prev;
02827     }
02828 
02829   do_cleanups (set_cleanups);
02830   gdb_bfd_unref (obfd);
02831   discard_cleanups (old_cleanups);
02832 
02833   /* Succeeded.  */
02834   printf_filtered (_("Saved core file %s with execution log.\n"),
02835                    recfilename);
02836 }
02837 
02838 /* record_full_goto_insn -- rewind the record log (forward or backward,
02839    depending on DIR) to the given entry, changing the program state
02840    correspondingly.  */
02841 
02842 static void
02843 record_full_goto_insn (struct record_full_entry *entry,
02844                        enum exec_direction_kind dir)
02845 {
02846   struct cleanup *set_cleanups = record_full_gdb_operation_disable_set ();
02847   struct regcache *regcache = get_current_regcache ();
02848   struct gdbarch *gdbarch = get_regcache_arch (regcache);
02849 
02850   /* Assume everything is valid: we will hit the entry,
02851      and we will not hit the end of the recording.  */
02852 
02853   if (dir == EXEC_FORWARD)
02854     record_full_list = record_full_list->next;
02855 
02856   do
02857     {
02858       record_full_exec_insn (regcache, gdbarch, record_full_list);
02859       if (dir == EXEC_REVERSE)
02860         record_full_list = record_full_list->prev;
02861       else
02862         record_full_list = record_full_list->next;
02863     } while (record_full_list != entry);
02864   do_cleanups (set_cleanups);
02865 }
02866 
02867 /* Alias for "target record-full".  */
02868 
02869 static void
02870 cmd_record_full_start (char *args, int from_tty)
02871 {
02872   execute_command ("target record-full", from_tty);
02873 }
02874 
02875 static void
02876 set_record_full_insn_max_num (char *args, int from_tty,
02877                               struct cmd_list_element *c)
02878 {
02879   if (record_full_insn_num > record_full_insn_max_num)
02880     {
02881       /* Count down record_full_insn_num while releasing records from list.  */
02882       while (record_full_insn_num > record_full_insn_max_num)
02883        {
02884          record_full_list_release_first ();
02885          record_full_insn_num--;
02886        }
02887     }
02888 }
02889 
02890 /* The "set record full" command.  */
02891 
02892 static void
02893 set_record_full_command (char *args, int from_tty)
02894 {
02895   printf_unfiltered (_("\"set record full\" must be followed "
02896                        "by an apporpriate subcommand.\n"));
02897   help_list (set_record_full_cmdlist, "set record full ", all_commands,
02898              gdb_stdout);
02899 }
02900 
02901 /* The "show record full" command.  */
02902 
02903 static void
02904 show_record_full_command (char *args, int from_tty)
02905 {
02906   cmd_show_list (show_record_full_cmdlist, from_tty, "");
02907 }
02908 
02909 /* Provide a prototype to silence -Wmissing-prototypes.  */
02910 extern initialize_file_ftype _initialize_record_full;
02911 
02912 void
02913 _initialize_record_full (void)
02914 {
02915   struct cmd_list_element *c;
02916 
02917   /* Init record_full_first.  */
02918   record_full_first.prev = NULL;
02919   record_full_first.next = NULL;
02920   record_full_first.type = record_full_end;
02921 
02922   init_record_full_ops ();
02923   add_target (&record_full_ops);
02924   add_deprecated_target_alias (&record_full_ops, "record");
02925   init_record_full_core_ops ();
02926   add_target (&record_full_core_ops);
02927 
02928   add_prefix_cmd ("full", class_obscure, cmd_record_full_start,
02929                   _("Start full execution recording."), &record_full_cmdlist,
02930                   "record full ", 0, &record_cmdlist);
02931 
02932   c = add_cmd ("restore", class_obscure, cmd_record_full_restore,
02933                _("Restore the execution log from a file.\n\
02934 Argument is filename.  File must be created with 'record save'."),
02935                &record_full_cmdlist);
02936   set_cmd_completer (c, filename_completer);
02937 
02938   /* Deprecate the old version without "full" prefix.  */
02939   c = add_alias_cmd ("restore", "full restore", class_obscure, 1,
02940                      &record_cmdlist);
02941   set_cmd_completer (c, filename_completer);
02942   deprecate_cmd (c, "record full restore");
02943 
02944   add_prefix_cmd ("full", class_support, set_record_full_command,
02945                   _("Set record options"), &set_record_full_cmdlist,
02946                   "set record full ", 0, &set_record_cmdlist);
02947 
02948   add_prefix_cmd ("full", class_support, show_record_full_command,
02949                   _("Show record options"), &show_record_full_cmdlist,
02950                   "show record full ", 0, &show_record_cmdlist);
02951 
02952   /* Record instructions number limit command.  */
02953   add_setshow_boolean_cmd ("stop-at-limit", no_class,
02954                            &record_full_stop_at_limit, _("\
02955 Set whether record/replay stops when record/replay buffer becomes full."), _("\
02956 Show whether record/replay stops when record/replay buffer becomes full."),
02957                            _("Default is ON.\n\
02958 When ON, if the record/replay buffer becomes full, ask user what to do.\n\
02959 When OFF, if the record/replay buffer becomes full,\n\
02960 delete the oldest recorded instruction to make room for each new one."),
02961                            NULL, NULL,
02962                            &set_record_full_cmdlist, &show_record_full_cmdlist);
02963 
02964   c = add_alias_cmd ("stop-at-limit", "full stop-at-limit", no_class, 1,
02965                      &set_record_cmdlist);
02966   deprecate_cmd (c, "set record full stop-at-limit");
02967 
02968   c = add_alias_cmd ("stop-at-limit", "full stop-at-limit", no_class, 1,
02969                      &show_record_cmdlist);
02970   deprecate_cmd (c, "show record full stop-at-limit");
02971 
02972   add_setshow_uinteger_cmd ("insn-number-max", no_class,
02973                             &record_full_insn_max_num,
02974                             _("Set record/replay buffer limit."),
02975                             _("Show record/replay buffer limit."), _("\
02976 Set the maximum number of instructions to be stored in the\n\
02977 record/replay buffer.  A value of either \"unlimited\" or zero means no\n\
02978 limit.  Default is 200000."),
02979                             set_record_full_insn_max_num,
02980                             NULL, &set_record_full_cmdlist,
02981                             &show_record_full_cmdlist);
02982 
02983   c = add_alias_cmd ("insn-number-max", "full insn-number-max", no_class, 1,
02984                      &set_record_cmdlist);
02985   deprecate_cmd (c, "set record full insn-number-max");
02986 
02987   c = add_alias_cmd ("insn-number-max", "full insn-number-max", no_class, 1,
02988                      &show_record_cmdlist);
02989   deprecate_cmd (c, "show record full insn-number-max");
02990 
02991   add_setshow_boolean_cmd ("memory-query", no_class,
02992                            &record_full_memory_query, _("\
02993 Set whether query if PREC cannot record memory change of next instruction."),
02994                            _("\
02995 Show whether query if PREC cannot record memory change of next instruction."),
02996                            _("\
02997 Default is OFF.\n\
02998 When ON, query if PREC cannot record memory change of next instruction."),
02999                            NULL, NULL,
03000                            &set_record_full_cmdlist,
03001                            &show_record_full_cmdlist);
03002 
03003   c = add_alias_cmd ("memory-query", "full memory-query", no_class, 1,
03004                      &set_record_cmdlist);
03005   deprecate_cmd (c, "set record full memory-query");
03006 
03007   c = add_alias_cmd ("memory-query", "full memory-query", no_class, 1,
03008                      &show_record_cmdlist);
03009   deprecate_cmd (c, "show record full memory-query");
03010 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines