mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2024-11-24 10:35:12 +08:00
2009-10-20 Hui Zhu <teawater@gmail.com>
Michael Snyder <msnyder@vmware.com> * record.c (record_exec_insn): New function. Emulate one instruction, forward or backward. Abstracted from record_wait. (record_wait) Call record_exec_insn.
This commit is contained in:
parent
4b06377fcc
commit
90ca047913
@ -1,3 +1,10 @@
|
||||
2009-10-20 Hui Zhu <teawater@gmail.com>
|
||||
Michael Snyder <msnyder@vmware.com>
|
||||
|
||||
* record.c (record_exec_insn): New function. Emulate one
|
||||
instruction, forward or backward. Abstracted from record_wait.
|
||||
(record_wait) Call record_exec_insn.
|
||||
|
||||
2009-10-20 Michael Snyder <msnyder@msnyder-server.eng.vmware.com>
|
||||
|
||||
* infrun.c (handle_inferior_event): Add pspace field to sal
|
||||
|
146
gdb/record.c
146
gdb/record.c
@ -585,6 +585,80 @@ record_gdb_operation_disable_set (void)
|
||||
return old_cleanups;
|
||||
}
|
||||
|
||||
/* Execute one instruction from the record log. Each instruction in
|
||||
the log will be represented by an arbitrary sequence of register
|
||||
entries and memory entries, followed by an 'end' entry. */
|
||||
|
||||
static inline void
|
||||
record_exec_insn (struct regcache *regcache, struct gdbarch *gdbarch,
|
||||
struct record_entry *entry)
|
||||
{
|
||||
switch (entry->type)
|
||||
{
|
||||
case record_reg: /* reg */
|
||||
{
|
||||
gdb_byte reg[MAX_REGISTER_SIZE];
|
||||
|
||||
if (record_debug > 1)
|
||||
fprintf_unfiltered (gdb_stdlog,
|
||||
"Process record: record_reg %s to "
|
||||
"inferior num = %d.\n",
|
||||
host_address_to_string (entry),
|
||||
entry->u.reg.num);
|
||||
|
||||
regcache_cooked_read (regcache, entry->u.reg.num, reg);
|
||||
regcache_cooked_write (regcache, entry->u.reg.num,
|
||||
record_get_loc (entry));
|
||||
memcpy (record_get_loc (entry), reg, entry->u.reg.len);
|
||||
}
|
||||
break;
|
||||
|
||||
case record_mem: /* mem */
|
||||
{
|
||||
/* Nothing to do if the entry is flagged not_accessible. */
|
||||
if (!entry->u.mem.mem_entry_not_accessible)
|
||||
{
|
||||
gdb_byte *mem = alloca (entry->u.mem.len);
|
||||
|
||||
if (record_debug > 1)
|
||||
fprintf_unfiltered (gdb_stdlog,
|
||||
"Process record: record_mem %s to "
|
||||
"inferior addr = %s len = %d.\n",
|
||||
host_address_to_string (entry),
|
||||
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);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (target_write_memory (entry->u.mem.addr,
|
||||
record_get_loc (entry),
|
||||
entry->u.mem.len))
|
||||
{
|
||||
entry->u.mem.mem_entry_not_accessible = 1;
|
||||
if (record_debug)
|
||||
warning (_("Process record: error writing memory at "
|
||||
"addr = %s len = %d."),
|
||||
paddress (gdbarch, entry->u.mem.addr),
|
||||
entry->u.mem.len);
|
||||
}
|
||||
else
|
||||
memcpy (record_get_loc (entry), mem, entry->u.mem.len);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
record_open (char *name, int from_tty)
|
||||
{
|
||||
@ -881,77 +955,9 @@ record_wait (struct target_ops *ops,
|
||||
break;
|
||||
}
|
||||
|
||||
/* Set ptid, register and memory according to record_list. */
|
||||
if (record_list->type == record_reg)
|
||||
{
|
||||
/* reg */
|
||||
gdb_byte reg[MAX_REGISTER_SIZE];
|
||||
if (record_debug > 1)
|
||||
fprintf_unfiltered (gdb_stdlog,
|
||||
"Process record: record_reg %s to "
|
||||
"inferior num = %d.\n",
|
||||
host_address_to_string (record_list),
|
||||
record_list->u.reg.num);
|
||||
regcache_cooked_read (regcache, record_list->u.reg.num, reg);
|
||||
regcache_cooked_write (regcache, record_list->u.reg.num,
|
||||
record_get_loc (record_list));
|
||||
memcpy (record_get_loc (record_list), reg,
|
||||
record_list->u.reg.len);
|
||||
}
|
||||
else if (record_list->type == record_mem)
|
||||
{
|
||||
/* mem */
|
||||
/* Nothing to do if the entry is flagged not_accessible. */
|
||||
if (!record_list->u.mem.mem_entry_not_accessible)
|
||||
{
|
||||
gdb_byte *mem = alloca (record_list->u.mem.len);
|
||||
if (record_debug > 1)
|
||||
fprintf_unfiltered (gdb_stdlog,
|
||||
"Process record: record_mem %s to "
|
||||
"inferior addr = %s len = %d.\n",
|
||||
host_address_to_string (record_list),
|
||||
paddress (gdbarch,
|
||||
record_list->u.mem.addr),
|
||||
record_list->u.mem.len);
|
||||
record_exec_insn (regcache, gdbarch, record_list);
|
||||
|
||||
if (target_read_memory (record_list->u.mem.addr, mem,
|
||||
record_list->u.mem.len))
|
||||
{
|
||||
if (execution_direction != EXEC_REVERSE)
|
||||
error (_("Process record: error reading memory at "
|
||||
"addr = %s len = %d."),
|
||||
paddress (gdbarch, record_list->u.mem.addr),
|
||||
record_list->u.mem.len);
|
||||
else
|
||||
/* Read failed --
|
||||
flag entry as not_accessible. */
|
||||
record_list->u.mem.mem_entry_not_accessible = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (target_write_memory (record_list->u.mem.addr,
|
||||
record_get_loc (record_list),
|
||||
record_list->u.mem.len))
|
||||
{
|
||||
if (execution_direction != EXEC_REVERSE)
|
||||
error (_("Process record: error writing memory at "
|
||||
"addr = %s len = %d."),
|
||||
paddress (gdbarch, record_list->u.mem.addr),
|
||||
record_list->u.mem.len);
|
||||
else
|
||||
/* Write failed --
|
||||
flag entry as not_accessible. */
|
||||
record_list->u.mem.mem_entry_not_accessible = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy (record_get_loc (record_list), mem,
|
||||
record_list->u.mem.len);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
if (record_list->type == record_end)
|
||||
{
|
||||
if (record_debug > 1)
|
||||
fprintf_unfiltered (gdb_stdlog,
|
||||
|
Loading…
Reference in New Issue
Block a user