2009-08-06 Michael Snyder <msnyder@vmware.com>

* record.c (cmd_record_dump): Clean up draft version.
	(cmd_record_load): Ditto.
This commit is contained in:
Michael Snyder
2009-08-07 02:53:15 +00:00
parent a77711c5df
commit b8586defc6
2 changed files with 294 additions and 443 deletions

View File

@@ -1,3 +1,8 @@
2009-08-06 Michael Snyder <msnyder@vmware.com>
* record.c (cmd_record_dump): Clean up draft version.
(cmd_record_load): Ditto.
2009-08-06 Hui Zhu <teawater@gmail.com> 2009-08-06 Hui Zhu <teawater@gmail.com>
Michael Snyder <msnyder@vmware.com> Michael Snyder <msnyder@vmware.com>
(Add record dump/load commands: draft version, not ready for release). (Add record dump/load commands: draft version, not ready for release).

View File

@@ -1252,6 +1252,14 @@ cmd_record_dump (char *args, int from_tty)
struct gdbarch *gdbarch; struct gdbarch *gdbarch;
struct cleanup *old_cleanups; struct cleanup *old_cleanups;
struct cleanup *set_cleanups; struct cleanup *set_cleanups;
extern void write_gcore_file (bfd *);
extern bfd *create_gcore_bfd (char *);
bfd *obfd;
int dump_size = 0;
asection *osec = NULL;
struct record_entry *p;
int bfd_offset = 0;
if (current_target.to_stratum != record_stratum) if (current_target.to_stratum != record_stratum)
error (_("Process record is not started.\n")); error (_("Process record is not started.\n"));
@@ -1271,181 +1279,167 @@ cmd_record_dump (char *args, int from_tty)
_("Saving recording to file '%s'\n"), _("Saving recording to file '%s'\n"),
recfilename); recfilename);
/* Michael-style, elf core dump file. */ /* Open the output file. */
{ obfd = create_gcore_bfd (recfilename);
extern void write_gcore_file (bfd *);
extern bfd *create_gcore_bfd (char *);
bfd *obfd;
int dump_size = 0;
asection *osec = NULL;
struct record_entry *p;
int bfd_offset = 0;
/* Open the output file. */ /* Need a cleanup that will close the file (FIXME: delete it?). */
obfd = create_gcore_bfd (recfilename); old_cleanups = make_cleanup_bfd_close (obfd);
/* Need a cleanup that will close the file (FIXME: delete it?). */ /* Save the current record entry to "cur_record_list". */
old_cleanups = make_cleanup_bfd_close (obfd); cur_record_list = record_list;
/* Save the current record entry to "cur_record_list". */ /* Get the values of regcache and gdbarch. */
cur_record_list = record_list; regcache = get_current_regcache ();
gdbarch = get_regcache_arch (regcache);
/* Get the values of regcache and gdbarch. */ /* Disable the GDB operation record. */
regcache = get_current_regcache (); set_cleanups = record_gdb_operation_disable_set ();
gdbarch = get_regcache_arch (regcache);
/* Disable the GDB operation record. */ /* Reverse execute to the begin of record list. */
set_cleanups = record_gdb_operation_disable_set (); for (; record_list && record_list != &record_first;
record_list = record_list->prev)
record_exec_entry (regcache, gdbarch, record_list);
/* Reverse execute to the begin of record list. */ /* Compute the size needed for the extra bfd section. */
for (; record_list && record_list != &record_first; dump_size = 4; /* magic cookie */
record_list = record_list->prev) for (p = &record_first; p; p = p->next)
switch (p->type)
{ {
record_exec_entry (regcache, gdbarch, record_list); case record_end:
dump_size += 1;
break;
case record_reg:
dump_size += 1 + 8 + MAX_REGISTER_SIZE;
break;
case record_mem:
dump_size += 1 + 8 + 8 + p->u.mem.len;
break;
} }
/* Compute the size needed for the extra bfd section. */ /* Make the new bfd section. */
dump_size = 4; /* magic cookie */ osec = bfd_make_section_anyway (obfd, "precord");
for (p = &record_first; p; p = p->next) bfd_set_section_size (obfd, osec, dump_size);
bfd_set_section_vma (obfd, osec, 0);
bfd_section_lma (obfd, osec) = 0;
bfd_set_section_flags (obfd, osec, SEC_ALLOC | SEC_HAS_CONTENTS);
/* Save corefile state. */
write_gcore_file (obfd);
/* Write out the record log (modified Hui method). */
/* Write the magic code. */
magic = RECORD_FILE_MAGIC;
if (record_debug)
fprintf_unfiltered (gdb_stdlog, _("\
Writing 4-byte magic cookie RECORD_FILE_MAGIC (0x%08x)\n"),
magic);
if (bfd_set_section_contents (obfd, osec, &magic,
bfd_offset, sizeof (magic)))
bfd_offset += sizeof (magic);
else
error (_("Failed to write 'magic' to %s (%s)"),
recfilename, bfd_errmsg (bfd_get_error ()));
/* Dump the entries into the new bfd section. */
for (p = &record_first; p; p = p->next)
{
uint8_t tmpu8;
uint64_t tmpu64;
tmpu8 = p->type;
if (bfd_set_section_contents (obfd, osec, &tmpu8,
bfd_offset, sizeof (tmpu8)))
bfd_offset += sizeof (tmpu8);
else
error (_("Failed to write 'type' to %s (%s)"),
recfilename, bfd_errmsg (bfd_get_error ()));
switch (p->type) switch (p->type)
{ {
case record_reg: /* reg */
tmpu64 = p->u.reg.num;
if (BYTE_ORDER == LITTLE_ENDIAN)
tmpu64 = bswap_64 (tmpu64);
if (record_debug)
fprintf_unfiltered (gdb_stdlog, _("\
Writing register %d val 0x%016llx (1 plus 8 plus %d bytes)\n"),
p->u.reg.num,
*(ULONGEST *) p->u.reg.val,
MAX_REGISTER_SIZE);
/* FIXME: register num does not need 8 bytes. */
if (bfd_set_section_contents (obfd, osec, &tmpu64,
bfd_offset, sizeof (tmpu64)))
bfd_offset += sizeof (tmpu64);
else
error (_("Failed to write regnum to %s (%s)"),
recfilename, bfd_errmsg (bfd_get_error ()));
/* FIXME: add a len field, and write the smaller value. */
if (bfd_set_section_contents (obfd, osec,
p->u.reg.val,
bfd_offset,
MAX_REGISTER_SIZE))
bfd_offset += MAX_REGISTER_SIZE;
else
error (_("Failed to write regval to %s (%s)"),
recfilename, bfd_errmsg (bfd_get_error ()));
break;
case record_mem: /* mem */
tmpu64 = p->u.mem.addr;
if (BYTE_ORDER == LITTLE_ENDIAN)
tmpu64 = bswap_64 (tmpu64);
if (record_debug)
fprintf_unfiltered (gdb_stdlog, _("\
Writing memory 0x%08x (1 plus 8 plus 8 bytes plus %d bytes)\n"),
(unsigned int) p->u.mem.addr,
p->u.mem.len);
if (bfd_set_section_contents (obfd, osec, &tmpu64,
bfd_offset, sizeof (tmpu64)))
bfd_offset += sizeof (tmpu64);
else
error (_("Failed to write memaddr to %s (%s)"),
recfilename, bfd_errmsg (bfd_get_error ()));
tmpu64 = p->u.mem.len;
if (BYTE_ORDER == LITTLE_ENDIAN)
tmpu64 = bswap_64 (tmpu64);
/* FIXME: len does not need 8 bytes. */
if (bfd_set_section_contents (obfd, osec, &tmpu64,
bfd_offset, sizeof (tmpu64)))
bfd_offset += sizeof (tmpu64);
else
error (_("Failed to write memlen to %s (%s)"),
recfilename, bfd_errmsg (bfd_get_error ()));
if (bfd_set_section_contents (obfd, osec,
p->u.mem.val,
bfd_offset,
p->u.mem.len))
bfd_offset += p->u.mem.len;
else
error (_("Failed to write memval to %s (%s)"),
recfilename, bfd_errmsg (bfd_get_error ()));
break;
case record_end: case record_end:
dump_size += 1; /* FIXME: record the contents of record_end rec. */
break; if (record_debug)
case record_reg: fprintf_unfiltered (gdb_stdlog, _("\
dump_size += 1 + 8 + MAX_REGISTER_SIZE; Writing record_end (1 byte)\n"));
break;
case record_mem:
dump_size += 1 + 8 + 8 + p->u.mem.len;
break; break;
} }
}
/* Make the new bfd section. */ /* Now forward-execute back to the saved entry. */
osec = bfd_make_section_anyway (obfd, "precord"); for (record_list = &record_first;
bfd_set_section_size (obfd, osec, dump_size); record_list && record_list != cur_record_list;
bfd_set_section_vma (obfd, osec, 0); record_list = record_list->next)
bfd_section_lma (obfd, osec) = 0; record_exec_entry (regcache, gdbarch, record_list);
bfd_set_section_flags (obfd, osec, SEC_ALLOC | SEC_HAS_CONTENTS);
/* Save corefile state. */ /* Clean-ups will close the output file and free malloc memory. */
write_gcore_file (obfd); do_cleanups (old_cleanups);
/* Write out the record log (modified Hui method). */
/* Write the magic code. */
magic = RECORD_FILE_MAGIC;
if (record_debug)
fprintf_unfiltered (gdb_stdlog, _("\
Writing 4-byte magic cookie RECORD_FILE_MAGIC (0x%08x)\n"),
magic);
if (bfd_set_section_contents (obfd, osec, &magic,
bfd_offset, sizeof (magic)))
bfd_offset += sizeof (magic);
else
error (_("Failed to write 'magic' to %s (%s)"),
recfilename, bfd_errmsg (bfd_get_error ()));
/* Dump the entries into the new bfd section. */
for (p = &record_first; p; p = p->next)
{
uint8_t tmpu8;
uint64_t tmpu64;
tmpu8 = p->type;
if (bfd_set_section_contents (obfd, osec, &tmpu8,
bfd_offset, sizeof (tmpu8)))
bfd_offset += sizeof (tmpu8);
else
error (_("Failed to write 'type' to %s (%s)"),
recfilename, bfd_errmsg (bfd_get_error ()));
switch (p->type)
{
case record_reg: /* reg */
tmpu64 = p->u.reg.num;
if (BYTE_ORDER == LITTLE_ENDIAN)
tmpu64 = bswap_64 (tmpu64);
if (record_debug)
fprintf_unfiltered (gdb_stdlog, _("\
Writing register %d val 0x%016llx (1 plus 8 plus %d bytes)\n"),
p->u.reg.num,
*(ULONGEST *) p->u.reg.val,
MAX_REGISTER_SIZE);
/* FIXME: register num does not need 8 bytes. */
if (bfd_set_section_contents (obfd, osec, &tmpu64,
bfd_offset, sizeof (tmpu64)))
bfd_offset += sizeof (tmpu64);
else
error (_("Failed to write regnum to %s (%s)"),
recfilename, bfd_errmsg (bfd_get_error ()));
/* FIXME: add a len field, and write the smaller value. */
if (bfd_set_section_contents (obfd, osec,
p->u.reg.val,
bfd_offset,
MAX_REGISTER_SIZE))
bfd_offset += MAX_REGISTER_SIZE;
else
error (_("Failed to write regval to %s (%s)"),
recfilename, bfd_errmsg (bfd_get_error ()));
break;
case record_mem: /* mem */
tmpu64 = p->u.mem.addr;
if (BYTE_ORDER == LITTLE_ENDIAN)
tmpu64 = bswap_64 (tmpu64);
if (record_debug)
fprintf_unfiltered (gdb_stdlog, _("\
Writing memory 0x%08x (1 plus 8 plus 8 bytes plus %d bytes)\n"),
(unsigned int) p->u.mem.addr,
p->u.mem.len);
if (bfd_set_section_contents (obfd, osec, &tmpu64,
bfd_offset, sizeof (tmpu64)))
bfd_offset += sizeof (tmpu64);
else
error (_("Failed to write memaddr to %s (%s)"),
recfilename, bfd_errmsg (bfd_get_error ()));
tmpu64 = p->u.mem.len;
if (BYTE_ORDER == LITTLE_ENDIAN)
tmpu64 = bswap_64 (tmpu64);
/* FIXME: len does not need 8 bytes. */
if (bfd_set_section_contents (obfd, osec, &tmpu64,
bfd_offset, sizeof (tmpu64)))
bfd_offset += sizeof (tmpu64);
else
error (_("Failed to write memlen to %s (%s)"),
recfilename, bfd_errmsg (bfd_get_error ()));
if (bfd_set_section_contents (obfd, osec,
p->u.mem.val,
bfd_offset,
p->u.mem.len))
bfd_offset += p->u.mem.len;
else
error (_("Failed to write memval to %s (%s)"),
recfilename, bfd_errmsg (bfd_get_error ()));
break;
case record_end:
/* FIXME: record the contents of record_end rec. */
if (record_debug)
fprintf_unfiltered (gdb_stdlog, _("\
Writing record_end (1 byte)\n"));
break;
}
}
/* Now forward-execute back to the saved entry. */
for (record_list = &record_first;
record_list && record_list != cur_record_list;
record_list = record_list->next)
{
record_exec_entry (regcache, gdbarch, record_list);
}
/* Clean-ups will close the output file and free malloc memory. */
do_cleanups (old_cleanups);
}
/* Succeeded. */ /* Succeeded. */
fprintf_filtered (gdb_stdout, "Saved recfile %s.\n", recfilename); fprintf_filtered (gdb_stdout, "Saved recfile %s.\n", recfilename);
@@ -1476,6 +1470,9 @@ cmd_record_load (char *args, int from_tty)
struct cleanup *old_cleanups2; struct cleanup *old_cleanups2;
struct record_entry *rec; struct record_entry *rec;
int insn_number = 0; int insn_number = 0;
bfd *core_bfd;
asection *osec;
extern bfd *load_corefile (char *, int);
if (!args || (args && !*args)) if (!args || (args && !*args))
error (_("Argument for filename required.\n")); error (_("Argument for filename required.\n"));
@@ -1484,316 +1481,165 @@ cmd_record_load (char *args, int from_tty)
if (record_debug) if (record_debug)
fprintf_unfiltered (gdb_stdlog, fprintf_unfiltered (gdb_stdlog,
_("Restoring recording from file '%s'\n"), args); _("Restoring recording from file '%s'\n"), args);
#if 1
/* Michael-style elf core dump file. */
{
bfd *core_bfd;
asection *osec;
extern bfd *load_corefile (char *, int);
/* Restore corefile regs and mem sections. */ /* Restore corefile regs and mem sections. */
core_bfd = load_corefile (args, from_tty); core_bfd = load_corefile (args, from_tty);
old_cleanups = make_cleanup_bfd_close (core_bfd); old_cleanups = make_cleanup_bfd_close (core_bfd);
/* Now need to find our special note section. */ /* Now need to find our special note section. */
osec = bfd_get_section_by_name (core_bfd, "null0"); osec = bfd_get_section_by_name (core_bfd, "null0");
printf_filtered ("Find precord section %s.\n", printf_filtered ("Find precord section %s.\n",
osec ? "succeeded" : "failed"); osec ? "succeeded" : "failed");
if (osec) if (osec)
{ {
int i, len; int i, len;
int bfd_offset = 0; int bfd_offset = 0;
printf_filtered ("osec name = '%s'\n", if (record_debug)
bfd_section_name (core_bfd, osec)); fprintf_unfiltered (gdb_stdlog, "osec name = '%s'\n",
len = (int) bfd_section_size (core_bfd, osec); bfd_section_name (core_bfd, osec));
printf_filtered ("osec size = %d\n", len); len = (int) bfd_section_size (core_bfd, osec);
printf_filtered ("osec size = %d\n", len);
/* Check the magic code. */ /* Check the magic code. */
if (!bfdcore_read (core_bfd, osec, &magic, if (!bfdcore_read (core_bfd, osec, &magic,
sizeof (magic), &bfd_offset)) sizeof (magic), &bfd_offset))
error (_("Failed to read 'magic' from %s (%s)"), error (_("Failed to read 'magic' from %s (%s)"),
args, bfd_errmsg (bfd_get_error ())); args, bfd_errmsg (bfd_get_error ()));
if (magic != RECORD_FILE_MAGIC) if (magic != RECORD_FILE_MAGIC)
error (_("'%s', version mis-match / file format error."), error (_("'%s', version mis-match / file format error."),
args); args);
if (record_debug) if (record_debug)
fprintf_unfiltered (gdb_stdlog, _("\ fprintf_unfiltered (gdb_stdlog, _("\
Reading 4-byte magic cookie RECORD_FILE_MAGIC (0x%08x)\n"), Reading 4-byte magic cookie RECORD_FILE_MAGIC (0x%08x)\n"),
magic); magic);
if (current_target.to_stratum != record_stratum) if (current_target.to_stratum != record_stratum)
{ {
/* FIXME need cleanup! We might error out. */ /* FIXME need cleanup! We might error out. */
cmd_record_start (NULL, from_tty); cmd_record_start (NULL, from_tty);
printf_unfiltered (_("Auto start process record.\n")); printf_unfiltered (_("Auto start process record.\n"));
} }
/* Load the entries in recfd to the record_arch_list_head and /* Free any existing record log, and load the entries in
record_arch_list_tail. */ core_bfd to the new record log. */
/* FIXME free old records? */ record_list_release (record_arch_list_tail);
record_list_release (record_arch_list_tail); record_arch_list_head = 0;
record_arch_list_head = NULL; record_arch_list_tail = 0;
record_arch_list_tail = NULL; old_cleanups2 = make_cleanup (record_message_cleanups, 0);
old_cleanups2 = make_cleanup (record_message_cleanups, 0);
while (1) while (1)
{ {
uint8_t tmpu8; uint8_t tmpu8;
uint64_t tmpu64; uint64_t tmpu64;
if (!bfdcore_read (core_bfd, osec, &tmpu8, /* FIXME: Check offset for end-of-section. */
sizeof (tmpu8), &bfd_offset)) if (!bfdcore_read (core_bfd, osec, &tmpu8,
break; sizeof (tmpu8), &bfd_offset))
break;
switch (tmpu8) switch (tmpu8)
{ {
case record_reg: /* reg */ case record_reg: /* reg */
/* FIXME: abstract out into an 'insert' function. */ /* FIXME: abstract out into an 'insert' function. */
rec = (struct record_entry *) rec = (struct record_entry *)
xmalloc (sizeof (struct record_entry)); xmalloc (sizeof (struct record_entry));
rec->u.reg.val = (gdb_byte *) xcalloc (1, MAX_REGISTER_SIZE); rec->u.reg.val = (gdb_byte *) xcalloc (1, MAX_REGISTER_SIZE);
rec->prev = NULL; rec->prev = NULL;
rec->next = NULL; rec->next = NULL;
rec->type = record_reg; rec->type = record_reg;
/* Get num. */ /* Get num. */
/* FIXME: register num does not need 8 bytes. */ /* FIXME: register num does not need 8 bytes. */
if (!bfdcore_read (core_bfd, osec, &tmpu64, if (!bfdcore_read (core_bfd, osec, &tmpu64,
sizeof (tmpu64), &bfd_offset)) sizeof (tmpu64), &bfd_offset))
error (_("Failed to read regnum from %s (%s)"), error (_("Failed to read regnum from %s (%s)"),
args, bfd_errmsg (bfd_get_error ())); args, bfd_errmsg (bfd_get_error ()));
if (BYTE_ORDER == LITTLE_ENDIAN) if (BYTE_ORDER == LITTLE_ENDIAN)
tmpu64 = bswap_64 (tmpu64); tmpu64 = bswap_64 (tmpu64);
rec->u.reg.num = tmpu64; rec->u.reg.num = tmpu64;
/* Get val. */ /* Get val. */
if (!bfdcore_read (core_bfd, osec, rec->u.reg.val, if (!bfdcore_read (core_bfd, osec, rec->u.reg.val,
MAX_REGISTER_SIZE, &bfd_offset)) MAX_REGISTER_SIZE, &bfd_offset))
error (_("Failed to read regval from %s (%s)"), error (_("Failed to read regval from %s (%s)"),
args, bfd_errmsg (bfd_get_error ())); args, bfd_errmsg (bfd_get_error ()));
if (record_debug) if (record_debug)
fprintf_unfiltered (gdb_stdlog, _("\ fprintf_unfiltered (gdb_stdlog, _("\
Reading register %d val 0x%016llx (1 plus 8 plus %d bytes)\n"), Reading register %d val 0x%016llx (1 plus 8 plus %d bytes)\n"),
rec->u.reg.num, rec->u.reg.num,
*(ULONGEST *) rec->u.reg.val, *(ULONGEST *) rec->u.reg.val,
MAX_REGISTER_SIZE); MAX_REGISTER_SIZE);
record_arch_list_add (rec); record_arch_list_add (rec);
break; break;
case record_mem: /* mem */ case record_mem: /* mem */
rec = (struct record_entry *) rec = (struct record_entry *)
xmalloc (sizeof (struct record_entry)); xmalloc (sizeof (struct record_entry));
rec->prev = NULL; rec->prev = NULL;
rec->next = NULL; rec->next = NULL;
rec->type = record_mem; rec->type = record_mem;
/* Get addr. */ /* Get addr. */
if (!bfdcore_read (core_bfd, osec, &tmpu64, if (!bfdcore_read (core_bfd, osec, &tmpu64,
sizeof (tmpu64), &bfd_offset)) sizeof (tmpu64), &bfd_offset))
error (_("Failed to read memaddr from %s (%s)"), error (_("Failed to read memaddr from %s (%s)"),
args, bfd_errmsg (bfd_get_error ())); args, bfd_errmsg (bfd_get_error ()));
if (BYTE_ORDER == LITTLE_ENDIAN) if (BYTE_ORDER == LITTLE_ENDIAN)
tmpu64 = bswap_64 (tmpu64); tmpu64 = bswap_64 (tmpu64);
rec->u.mem.addr = tmpu64; rec->u.mem.addr = tmpu64;
/* Get len. */ /* Get len. */
/* FIXME: len does not need 8 bytes. */ /* FIXME: len does not need 8 bytes. */
if (!bfdcore_read (core_bfd, osec, &tmpu64, if (!bfdcore_read (core_bfd, osec, &tmpu64,
sizeof (tmpu64), &bfd_offset)) sizeof (tmpu64), &bfd_offset))
error (_("Failed to read memlen from %s (%s)"), error (_("Failed to read memlen from %s (%s)"),
args, bfd_errmsg (bfd_get_error ())); args, bfd_errmsg (bfd_get_error ()));
if (BYTE_ORDER == LITTLE_ENDIAN) if (BYTE_ORDER == LITTLE_ENDIAN)
tmpu64 = bswap_64 (tmpu64); tmpu64 = bswap_64 (tmpu64);
rec->u.mem.len = tmpu64; rec->u.mem.len = tmpu64;
rec->u.mem.mem_entry_not_accessible = 0; rec->u.mem.mem_entry_not_accessible = 0;
rec->u.mem.val = (gdb_byte *) xmalloc (rec->u.mem.len); rec->u.mem.val = (gdb_byte *) xmalloc (rec->u.mem.len);
/* Get val. */ /* Get val. */
if (!bfdcore_read (core_bfd, osec, rec->u.mem.val, if (!bfdcore_read (core_bfd, osec, rec->u.mem.val,
rec->u.mem.len, &bfd_offset)) rec->u.mem.len, &bfd_offset))
error (_("Failed to read memval from %s (%s)"), error (_("Failed to read memval from %s (%s)"),
args, bfd_errmsg (bfd_get_error ())); args, bfd_errmsg (bfd_get_error ()));
if (record_debug) if (record_debug)
fprintf_unfiltered (gdb_stdlog, _("\ fprintf_unfiltered (gdb_stdlog, _("\
Reading memory 0x%08x (1 plus 8 plus %d bytes)\n"), Reading memory 0x%08x (1 plus 8 plus %d bytes)\n"),
(unsigned int) rec->u.mem.addr, (unsigned int) rec->u.mem.addr,
rec->u.mem.len); rec->u.mem.len);
record_arch_list_add (rec); record_arch_list_add (rec);
break; break;
case record_end: /* end */ case record_end: /* end */
/* FIXME: restore the contents of record_end rec. */ /* FIXME: restore the contents of record_end rec. */
rec = (struct record_entry *) rec = (struct record_entry *)
xmalloc (sizeof (struct record_entry)); xmalloc (sizeof (struct record_entry));
rec->prev = NULL; rec->prev = NULL;
rec->next = NULL; rec->next = NULL;
rec->type = record_end; rec->type = record_end;
if (record_debug) if (record_debug)
fprintf_unfiltered (gdb_stdlog, _("\ fprintf_unfiltered (gdb_stdlog, _("\
Reading record_end (one byte)\n")); Reading record_end (one byte)\n"));
record_arch_list_add (rec); record_arch_list_add (rec);
insn_number ++; insn_number ++;
break; break;
default: default:
error (_("Format of '%s' is not right."), args); error (_("Format of '%s' is not right."), args);
break; break;
}
} }
}
}
discard_cleanups (old_cleanups2);
/* Add record_arch_list_head to the end of record list. (??? FIXME)*/
for (rec = record_list; rec->next; rec = rec->next);
rec->next = record_arch_list_head;
record_arch_list_head->prev = rec;
/* Update record_insn_num and record_insn_max_num. */
record_insn_num += insn_number;
if (record_insn_num > record_insn_max_num)
{
record_insn_max_num = record_insn_num;
warning (_("Auto increase record/replay buffer limit to %d."),
record_insn_max_num);
}
do_cleanups (old_cleanups);
}
#endif
#if 0
/* Hui-style binary dump file. */
recfd = open (args, O_RDONLY | O_BINARY);
if (recfd < 0)
error (_("Failed to open '%s' for load."), args);
old_cleanups = make_cleanup (cmd_record_fd_cleanups, &recfd);
/* Check the magic code. */
if (read (recfd, &magic, 4) != 4)
error (_("Failed to read '%s' for load."), args);
if (magic != RECORD_FILE_MAGIC)
error (_("'%s' is not a record dump."), args);
if (record_debug)
fprintf_unfiltered (gdb_stdlog, _("\
Reading 4-byte magic cookie RECORD_FILE_MAGIC (0x%08x)\n"),
magic);
if (current_target.to_stratum != record_stratum)
{
/* FIXME need cleanup! We might error out. */
cmd_record_start (NULL, from_tty);
printf_unfiltered (_("Auto start process record.\n"));
}
/* Load the entries in recfd to the record_arch_list_head and
record_arch_list_tail. */
record_arch_list_head = NULL;
record_arch_list_tail = NULL;
old_cleanups2 = make_cleanup (record_message_cleanups, 0);
while (1)
{
int ret;
uint8_t tmpu8;
uint64_t tmpu64;
ret = read (recfd, &tmpu8, 1);
if (ret < 0)
error (_("Failed to read '%s' for load."), args);
if (ret == 0)
break;
switch (tmpu8)
{
case record_reg: /* reg */
/* FIXME: abstract out into an 'insert' function. */
rec = (struct record_entry *) xmalloc (sizeof (struct record_entry));
rec->u.reg.val = (gdb_byte *) xcalloc (1, MAX_REGISTER_SIZE);
rec->prev = NULL;
rec->next = NULL;
rec->type = record_reg;
/* Get num. */
/* FIXME: register num does not need 8 bytes. */
if (read (recfd, &tmpu64, 8) != 8)
error (_("Failed to read '%s' for load."), args);
if (BYTE_ORDER == LITTLE_ENDIAN)
tmpu64 = bswap_64 (tmpu64);
rec->u.reg.num = tmpu64;
/* Get val. */
if (read (recfd, rec->u.reg.val,
MAX_REGISTER_SIZE) != MAX_REGISTER_SIZE)
error (_("Failed to read '%s' for load."), args);
if (record_debug)
fprintf_unfiltered (gdb_stdlog, _("\
Reading register %d val 0x%016llx (1 plus 8 plus %d bytes)\n"),
rec->u.reg.num,
*(ULONGEST *) rec->u.reg.val,
MAX_REGISTER_SIZE);
record_arch_list_add (rec);
break;
case record_mem: /* mem */
rec = (struct record_entry *) xmalloc (sizeof (struct record_entry));
rec->prev = NULL;
rec->next = NULL;
rec->type = record_mem;
/* Get addr. */
if (read (recfd, &tmpu64, 8) != 8)
error (_("Failed to read '%s' for load."), args);
if (BYTE_ORDER == LITTLE_ENDIAN)
tmpu64 = bswap_64 (tmpu64);
rec->u.mem.addr = tmpu64;
/* Get len. */
/* FIXME: len does not need 8 bytes. */
if (read (recfd, &tmpu64, 8) != 8)
error (_("Failed to read '%s' for load."), args);
if (BYTE_ORDER == LITTLE_ENDIAN)
tmpu64 = bswap_64 (tmpu64);
rec->u.mem.len = tmpu64;
rec->u.mem.mem_entry_not_accessible = 0;
rec->u.mem.val = (gdb_byte *) xmalloc (rec->u.mem.len);
/* Get val. */
if (read (recfd, rec->u.mem.val,
rec->u.mem.len) != rec->u.mem.len)
error (_("Failed to read '%s' for load."), args);
if (record_debug)
fprintf_unfiltered (gdb_stdlog, _("\
Reading memory 0x%08x (1 plus 8 plus %d bytes)\n"),
(unsigned int) rec->u.mem.addr,
rec->u.mem.len);
record_arch_list_add (rec);
break;
case record_end: /* end */
/* FIXME: restore the contents of record_end rec. */
rec = (struct record_entry *) xmalloc (sizeof (struct record_entry));
rec->prev = NULL;
rec->next = NULL;
rec->type = record_end;
if (record_debug)
fprintf_unfiltered (gdb_stdlog, _("\
Reading record_end (one byte)\n"));
record_arch_list_add (rec);
insn_number ++;
break;
default:
error (_("Format of '%s' is not right."), args);
break;
}
} }
discard_cleanups (old_cleanups2); discard_cleanups (old_cleanups2);
/* Add record_arch_list_head to the end of record list. */ /* Add record_arch_list_head to the end of record list. (??? FIXME)*/
for (rec = record_list; rec->next; rec = rec->next); for (rec = record_list; rec->next; rec = rec->next);
rec->next = record_arch_list_head; rec->next = record_arch_list_head;
record_arch_list_head->prev = rec; record_arch_list_head->prev = rec;
@@ -1804,11 +1650,11 @@ cmd_record_load (char *args, int from_tty)
{ {
record_insn_max_num = record_insn_num; record_insn_max_num = record_insn_num;
warning (_("Auto increase record/replay buffer limit to %d."), warning (_("Auto increase record/replay buffer limit to %d."),
record_insn_max_num); record_insn_max_num);
} }
do_cleanups (old_cleanups); do_cleanups (old_cleanups);
#endif
/* Succeeded. */ /* Succeeded. */
fprintf_filtered (gdb_stdout, "Loaded recfile %s.\n", args); fprintf_filtered (gdb_stdout, "Loaded recfile %s.\n", args);
registers_changed (); registers_changed ();