2009-10-15 Michael Snyder <msnyder@vmware.com>

* record.c (record_reg_alloc): New function.
	(record_reg_release): New function.
	(record_mem_alloc): New function.
	(record_mem_release): New function.
	(record_end_alloc): New function.
	(record_end_release): New function.
	(record_entry_release): New function.
	(record_list_release): Simplify, call record_entry_release.
	(record_list_release_next): Rename to record_list_release_following.
	Simplify and call record_entry_release.
	(record_list_release_first): Simplify, comment, and use
	record_entry_release.
	(record_arch_list_add_reg): Simplify, call record_reg_alloc.
	(record_arch_list_add_mem): Simplify, call record_mem_alloc.
	(record_arch_list_add_end): Simplify, call record_end_alloc.
This commit is contained in:
Michael Snyder
2009-10-15 17:15:56 +00:00
parent 3fce87a0af
commit 61f75dd8bf
2 changed files with 158 additions and 66 deletions

@ -1,4 +1,22 @@
2009-10-12 Michael Snyder <msnyder@vmware.com> 2009-10-15 Michael Snyder <msnyder@vmware.com>
* record.c (record_reg_alloc): New function.
(record_reg_release): New function.
(record_mem_alloc): New function.
(record_mem_release): New function.
(record_end_alloc): New function.
(record_end_release): New function.
(record_entry_release): New function.
(record_list_release): Simplify, call record_entry_release.
(record_list_release_next): Rename to record_list_release_following.
Simplify and call record_entry_release.
(record_list_release_first): Simplify, comment, and use
record_entry_release.
(record_arch_list_add_reg): Simplify, call record_reg_alloc.
(record_arch_list_add_mem): Simplify, call record_mem_alloc.
(record_arch_list_add_end): Simplify, call record_end_alloc.
2009-10-14 Michael Snyder <msnyder@vmware.com>
* record.c (record_list_release_first): Do not decrement * record.c (record_list_release_first): Do not decrement
record_insn_num. record_insn_num.

@ -129,50 +129,143 @@ static int (*record_beneath_to_insert_breakpoint) (struct gdbarch *,
static int (*record_beneath_to_remove_breakpoint) (struct gdbarch *, static int (*record_beneath_to_remove_breakpoint) (struct gdbarch *,
struct bp_target_info *); struct bp_target_info *);
/* Alloc and free functions for record_reg, record_mem, and record_end
entries. */
/* Alloc a record_reg record entry. */
static inline struct record_entry *
record_reg_alloc (struct regcache *regcache, int regnum)
{
struct record_entry *rec;
struct gdbarch *gdbarch = get_regcache_arch (regcache);
rec = (struct record_entry *) xcalloc (1, sizeof (struct record_entry));
rec->type = record_reg;
rec->u.reg.num = regnum;
rec->u.reg.val = (gdb_byte *) xmalloc (MAX_REGISTER_SIZE);
return rec;
}
/* Free a record_reg record entry. */
static inline void
record_reg_release (struct record_entry *rec)
{
gdb_assert (rec->type == record_reg);
xfree (rec->u.reg.val);
xfree (rec);
}
/* Alloc a record_mem record entry. */
static inline struct record_entry *
record_mem_alloc (CORE_ADDR addr, int len)
{
struct record_entry *rec;
rec = (struct record_entry *) xcalloc (1, sizeof (struct record_entry));
rec->type = record_mem;
rec->u.mem.addr = addr;
rec->u.mem.len = len;
rec->u.mem.val = (gdb_byte *) xmalloc (len);
return rec;
}
/* Free a record_mem record entry. */
static inline void
record_mem_release (struct record_entry *rec)
{
gdb_assert (rec->type == record_mem);
xfree (rec->u.mem.val);
xfree (rec);
}
/* Alloc a record_end record entry. */
static inline struct record_entry *
record_end_alloc (void)
{
struct record_entry *rec;
rec = (struct record_entry *) xcalloc (1, sizeof (struct record_entry));
rec->type = record_end;
return rec;
}
/* Free a record_end record entry. */
static inline void
record_end_release (struct record_entry *rec)
{
xfree (rec);
}
/* Free one record entry, any type.
Return entry->type, in case caller wants to know. */
static inline enum record_type
record_entry_release (struct record_entry *rec)
{
enum record_type type = rec->type;
switch (type) {
case record_reg:
record_reg_release (rec);
break;
case record_mem:
record_mem_release (rec);
break;
case record_end:
record_end_release (rec);
break;
}
return type;
}
/* Free all record entries in list pointed to by REC. */
static void static void
record_list_release (struct record_entry *rec) record_list_release (struct record_entry *rec)
{ {
struct record_entry *tmp;
if (!rec) if (!rec)
return; return;
while (rec->next) while (rec->next)
{
rec = rec->next; rec = rec->next;
}
while (rec->prev) while (rec->prev)
{ {
tmp = rec;
rec = rec->prev; rec = rec->prev;
if (tmp->type == record_reg) record_entry_release (rec->next);
xfree (tmp->u.reg.val);
else if (tmp->type == record_mem)
xfree (tmp->u.mem.val);
xfree (tmp);
} }
if (rec != &record_first) if (rec == &record_first)
xfree (rec); {
record_insn_num = 0;
record_first.next = NULL;
}
else
record_entry_release (rec);
} }
/* Free all record entries forward of the given list position. */
static void static void
record_list_release_next (void) record_list_release_following (struct record_entry *rec)
{ {
struct record_entry *rec = record_list;
struct record_entry *tmp = rec->next; struct record_entry *tmp = rec->next;
rec->next = NULL; rec->next = NULL;
while (tmp) while (tmp)
{ {
rec = tmp->next; rec = tmp->next;
if (tmp->type == record_end) if (record_entry_release (tmp) == record_end)
record_insn_num--; record_insn_num--;
else if (tmp->type == record_reg)
xfree (tmp->u.reg.val);
else if (tmp->type == record_mem)
xfree (tmp->u.mem.val);
xfree (tmp);
tmp = rec; tmp = rec;
} }
} }
@ -185,34 +278,31 @@ record_list_release_next (void)
static void static void
record_list_release_first (void) record_list_release_first (void)
{ {
struct record_entry *tmp = NULL; struct record_entry *tmp;
enum record_type type;
if (!record_first.next) if (!record_first.next)
return; return;
/* Loop until a record_end. */
while (1) while (1)
{ {
type = record_first.next->type; /* Cut record_first.next out of the linked list. */
if (type == record_reg)
xfree (record_first.next->u.reg.val);
else if (type == record_mem)
xfree (record_first.next->u.mem.val);
tmp = record_first.next; tmp = record_first.next;
record_first.next = tmp->next; record_first.next = tmp->next;
xfree (tmp); tmp->next->prev = &record_first;
/* tmp is now isolated, and can be deleted. */
if (record_entry_release (tmp) == record_end)
{
record_insn_num--;
break; /* End loop at first record_end. */
}
if (!record_first.next) if (!record_first.next)
{ {
gdb_assert (record_insn_num == 1); gdb_assert (record_insn_num == 1);
break; break; /* End loop when list is empty. */
} }
record_first.next->prev = &record_first;
if (type == record_end)
break;
} }
} }
@ -239,10 +329,10 @@ record_arch_list_add (struct record_entry *rec)
} }
} }
/* Record the value of a register NUM to record_arch_list. */ /* Record the value of a register REGNUM to record_arch_list. */
int int
record_arch_list_add_reg (struct regcache *regcache, int num) record_arch_list_add_reg (struct regcache *regcache, int regnum)
{ {
struct record_entry *rec; struct record_entry *rec;
@ -250,16 +340,11 @@ record_arch_list_add_reg (struct regcache *regcache, int num)
fprintf_unfiltered (gdb_stdlog, fprintf_unfiltered (gdb_stdlog,
"Process record: add register num = %d to " "Process record: add register num = %d to "
"record list.\n", "record list.\n",
num); regnum);
rec = (struct record_entry *) xmalloc (sizeof (struct record_entry)); rec = record_reg_alloc (regcache, regnum);
rec->u.reg.val = (gdb_byte *) xmalloc (MAX_REGISTER_SIZE);
rec->prev = NULL;
rec->next = NULL;
rec->type = record_reg;
rec->u.reg.num = num;
regcache_raw_read (regcache, num, rec->u.reg.val); regcache_raw_read (regcache, regnum, rec->u.reg.val);
record_arch_list_add (rec); record_arch_list_add (rec);
@ -280,17 +365,10 @@ record_arch_list_add_mem (CORE_ADDR addr, int len)
"record list.\n", "record list.\n",
paddress (target_gdbarch, addr), len); paddress (target_gdbarch, addr), len);
if (!addr) if (!addr) /* FIXME: Why? Some arch must permit it... */
return 0; return 0;
rec = (struct record_entry *) xmalloc (sizeof (struct record_entry)); rec = record_mem_alloc (addr, len);
rec->u.mem.val = (gdb_byte *) xmalloc (len);
rec->prev = NULL;
rec->next = NULL;
rec->type = record_mem;
rec->u.mem.addr = addr;
rec->u.mem.len = len;
rec->u.mem.mem_entry_not_accessible = 0;
if (target_read_memory (addr, rec->u.mem.val, len)) if (target_read_memory (addr, rec->u.mem.val, len))
{ {
@ -299,8 +377,7 @@ record_arch_list_add_mem (CORE_ADDR addr, int len)
"Process record: error reading memory at " "Process record: error reading memory at "
"addr = %s len = %d.\n", "addr = %s len = %d.\n",
paddress (target_gdbarch, addr), len); paddress (target_gdbarch, addr), len);
xfree (rec->u.mem.val); record_mem_release (rec);
xfree (rec);
return -1; return -1;
} }
@ -320,10 +397,7 @@ record_arch_list_add_end (void)
fprintf_unfiltered (gdb_stdlog, fprintf_unfiltered (gdb_stdlog,
"Process record: add end to arch list.\n"); "Process record: add end to arch list.\n");
rec = (struct record_entry *) xmalloc (sizeof (struct record_entry)); rec = record_end_alloc ();
rec->prev = NULL;
rec->next = NULL;
rec->type = record_end;
rec->u.end.sigval = TARGET_SIGNAL_0; rec->u.end.sigval = TARGET_SIGNAL_0;
record_arch_list_add (rec); record_arch_list_add (rec);
@ -1059,7 +1133,7 @@ record_store_registers (struct target_ops *ops, struct regcache *regcache,
} }
/* Destroy the record from here forward. */ /* Destroy the record from here forward. */
record_list_release_next (); record_list_release_following (record_list);
} }
record_registers_change (regcache, regno); record_registers_change (regcache, regno);
@ -1091,7 +1165,7 @@ record_xfer_partial (struct target_ops *ops, enum target_object object,
error (_("Process record canceled the operation.")); error (_("Process record canceled the operation."));
/* Destroy the record from here forward. */ /* Destroy the record from here forward. */
record_list_release_next (); record_list_release_following (record_list);
} }
/* Check record_insn_num */ /* Check record_insn_num */
@ -1231,7 +1305,7 @@ cmd_record_delete (char *args, int from_tty)
if (!from_tty || query (_("Delete the log from this point forward " if (!from_tty || query (_("Delete the log from this point forward "
"and begin to record the running message " "and begin to record the running message "
"at current PC?"))) "at current PC?")))
record_list_release_next (); record_list_release_following (record_list);
} }
else else
printf_unfiltered (_("Already at end of record list.\n")); printf_unfiltered (_("Already at end of record list.\n"));