#include "gcore.h"
#include "event-loop.h"
#include "inf-loop.h"
+#include "gdb_bfd.h"
#include <signal.h>
struct record_end_entry
{
- enum target_signal sigval;
+ enum gdb_signal sigval;
ULONGEST insn_num;
};
/* The beneath function pointers. */
static struct target_ops *record_beneath_to_resume_ops;
static void (*record_beneath_to_resume) (struct target_ops *, ptid_t, int,
- enum target_signal);
+ enum gdb_signal);
static struct target_ops *record_beneath_to_wait_ops;
static ptid_t (*record_beneath_to_wait) (struct target_ops *, ptid_t,
struct target_waitstatus *,
return 0;
}
+int
+record_read_memory (struct gdbarch *gdbarch,
+ CORE_ADDR memaddr, gdb_byte *myaddr,
+ ssize_t len)
+{
+ int ret = target_read_memory (memaddr, myaddr, len);
+
+ if (ret && record_debug)
+ printf_unfiltered (_("Process record: error reading memory "
+ "at addr %s len = %ld.\n"),
+ paddress (gdbarch, memaddr), (long) len);
+ return ret;
+}
+
/* Record the value of a region of memory whose address is ADDR and
length is LEN to record_arch_list. */
rec = record_mem_alloc (addr, len);
- if (target_read_memory (addr, record_get_loc (rec), len))
+ if (record_read_memory (target_gdbarch, addr, record_get_loc (rec), len))
{
- if (record_debug)
- fprintf_unfiltered (gdb_stdlog,
- "Process record: error reading memory at "
- "addr = %s len = %d.\n",
- paddress (target_gdbarch, addr), len);
record_mem_release (rec);
return -1;
}
"Process record: add end to arch list.\n");
rec = record_end_alloc ();
- rec->u.end.sigval = TARGET_SIGNAL_0;
+ rec->u.end.sigval = GDB_SIGNAL_0;
rec->u.end.insn_num = ++record_insn_count;
record_arch_list_add (rec);
record_arch_list, and add it to record_list. */
static int
-record_message (struct regcache *regcache, enum target_signal signal)
+record_message (struct regcache *regcache, enum gdb_signal signal)
{
int ret;
struct gdbarch *gdbarch = get_regcache_arch (regcache);
record_list->u.end.sigval = signal;
}
- if (signal == TARGET_SIGNAL_0
+ if (signal == GDB_SIGNAL_0
|| !gdbarch_process_record_signal_p (gdbarch))
ret = gdbarch_process_record (gdbarch,
regcache,
struct record_message_args {
struct regcache *regcache;
- enum target_signal signal;
+ enum gdb_signal signal;
};
static int
static int
record_message_wrapper_safe (struct regcache *regcache,
- enum target_signal signal)
+ enum gdb_signal signal)
{
struct record_message_args args;
paddress (gdbarch, entry->u.mem.addr),
entry->u.mem.len);
- if (target_read_memory (entry->u.mem.addr, mem, entry->u.mem.len))
- {
- entry->u.mem.mem_entry_not_accessible = 1;
- if (record_debug)
- warning (_("Process record: error reading memory at "
- "addr = %s len = %d."),
- paddress (gdbarch, entry->u.mem.addr),
- entry->u.mem.len);
- }
+ if (record_read_memory (gdbarch,
+ entry->u.mem.addr, mem, entry->u.mem.len))
+ entry->u.mem.mem_entry_not_accessible = 1;
else
{
if (target_write_memory (entry->u.mem.addr,
static struct target_ops *tmp_to_resume_ops;
static void (*tmp_to_resume) (struct target_ops *, ptid_t, int,
- enum target_signal);
+ enum gdb_signal);
static struct target_ops *tmp_to_wait_ops;
static ptid_t (*tmp_to_wait) (struct target_ops *, ptid_t,
struct target_waitstatus *,
push_target (&record_ops);
}
+static void record_init_record_breakpoints (void);
+
/* "to_open" target method. Open the process record target. */
static void
record_async_inferior_event_token
= create_async_event_handler (record_async_inferior_event_handler,
NULL);
+
+ record_init_record_breakpoints ();
}
/* "to_close" target method. Close the process record target. */
static void
record_resume (struct target_ops *ops, ptid_t ptid, int step,
- enum target_signal signal)
+ enum gdb_signal signal)
{
record_resume_step = step;
record_resumed = 1;
}
}
+ /* Make sure the target beneath reports all signals. */
+ target_pass_signals (0, NULL);
+
record_beneath_to_resume (record_beneath_to_resume_ops,
ptid, step, signal);
}
/* Is this a SIGTRAP? */
if (status->kind == TARGET_WAITKIND_STOPPED
- && status->value.sig == TARGET_SIGNAL_TRAP)
+ && status->value.sig == GDB_SIGNAL_TRAP)
{
struct regcache *regcache;
struct address_space *aspace;
int step = 1;
if (!record_message_wrapper_safe (regcache,
- TARGET_SIGNAL_0))
+ GDB_SIGNAL_0))
{
status->kind = TARGET_WAITKIND_STOPPED;
- status->value.sig = TARGET_SIGNAL_0;
+ status->value.sig = GDB_SIGNAL_0;
break;
}
"issuing one more step in the target beneath\n");
record_beneath_to_resume (record_beneath_to_resume_ops,
ptid, step,
- TARGET_SIGNAL_0);
+ GDB_SIGNAL_0);
continue;
}
}
continue_flag = 0;
}
/* Check target signal */
- if (record_list->u.end.sigval != TARGET_SIGNAL_0)
+ if (record_list->u.end.sigval != GDB_SIGNAL_0)
/* FIXME: better way to check */
continue_flag = 0;
}
replay_out:
if (record_get_sig)
- status->value.sig = TARGET_SIGNAL_INT;
- else if (record_list->u.end.sigval != TARGET_SIGNAL_0)
+ status->value.sig = GDB_SIGNAL_INT;
+ else if (record_list->u.end.sigval != GDB_SIGNAL_0)
/* FIXME: better way to check */
status->value.sig = record_list->u.end.sigval;
else
- status->value.sig = TARGET_SIGNAL_TRAP;
+ status->value.sig = GDB_SIGNAL_TRAP;
discard_cleanups (old_cleanups);
}
active. */
VEC(record_breakpoint_p) *record_breakpoints = NULL;
+static void
+record_sync_record_breakpoints (struct bp_location *loc, void *data)
+{
+ if (loc->loc_type != bp_loc_software_breakpoint)
+ return;
+
+ if (loc->inserted)
+ {
+ struct record_breakpoint *bp = XNEW (struct record_breakpoint);
+
+ bp->addr = loc->target_info.placed_address;
+ bp->address_space = loc->target_info.placed_address_space;
+
+ bp->in_target_beneath = 1;
+
+ VEC_safe_push (record_breakpoint_p, record_breakpoints, bp);
+ }
+}
+
+/* Sync existing breakpoints to record_breakpoints. */
+
+static void
+record_init_record_breakpoints (void)
+{
+ VEC_free (record_breakpoint_p, record_breakpoints);
+
+ iterate_over_bp_locations (record_sync_record_breakpoints);
+}
+
/* Behavior is conditional on RECORD_IS_REPLAY. We will not actually
insert or remove breakpoints in the real target when replaying, nor
when recording. */
static void
record_core_resume (struct target_ops *ops, ptid_t ptid, int step,
- enum target_signal signal)
+ enum gdb_signal signal)
{
record_resume_step = step;
record_resumed = 1;
bfd *obfd = data;
char *pathname = xstrdup (bfd_get_filename (obfd));
- bfd_close (obfd);
+ gdb_bfd_unref (obfd);
unlink (pathname);
xfree (pathname);
}
}
do_cleanups (set_cleanups);
- bfd_close (obfd);
+ gdb_bfd_unref (obfd);
discard_cleanups (old_cleanups);
/* Succeeded. */
print_stack_frame (get_selected_frame (NULL), 1, SRC_AND_LOC);
}
+/* Provide a prototype to silence -Wmissing-prototypes. */
+extern initialize_file_ftype _initialize_record;
+
void
_initialize_record (void)
{