summaryrefslogtreecommitdiff
path: root/gdb/ax-general.c
diff options
context:
space:
mode:
authorHui Zhu <teawater@gmail.com>2010-12-28 16:00:07 +0000
committerHui Zhu <teawater@gmail.com>2010-12-28 16:00:07 +0000
commit4d4d40dc46626e349e4c8ccac3794e526f8d4612 (patch)
tree20ef30783e61d13b3cb1e4f3d8702d86a1ad4a9a /gdb/ax-general.c
parent696c2599d17f385ce997ce9711c1a4be7c2c0584 (diff)
downloadgdb-4d4d40dc46626e349e4c8ccac3794e526f8d4612.tar.gz
2010-12-28 Hui Zhu <teawater@gmail.com>
* gdbarch.sh (ax_pseudo_register_collect, ax_pseudo_register_push_stack): new callbacks. (agent_expr): Forward declare. * gdbarch.h, gdbarch.c: Regenerate. * ax-gdb.c (gen_expr): Remove pseudo-register check code. * ax-general.c (user-regs.h): New include. (ax_reg): Call gdbarch_ax_pseudo_register_push_stack. (ax_reg_mask): Call gdbarch_ax_pseudo_register_collect. * mips-tdep.c (ax.h): New include. (mips_ax_pseudo_register_collect, mips_ax_pseudo_register_push_stack): New functions. (mips_gdbarch_init): Set mips_ax_pseudo_register_collect and mips_ax_pseudo_register_push_stack.
Diffstat (limited to 'gdb/ax-general.c')
-rw-r--r--gdb/ax-general.c77
1 files changed, 54 insertions, 23 deletions
diff --git a/gdb/ax-general.c b/gdb/ax-general.c
index ab4591fa088..e1269e6ff10 100644
--- a/gdb/ax-general.c
+++ b/gdb/ax-general.c
@@ -28,6 +28,8 @@
#include "value.h"
#include "gdb_string.h"
+#include "user-regs.h"
+
static void grow_expr (struct agent_expr *x, int n);
static void append_const (struct agent_expr *x, LONGEST val, int n);
@@ -272,14 +274,28 @@ ax_const_d (struct agent_expr *x, LONGEST d)
void
ax_reg (struct agent_expr *x, int reg)
{
- /* Make sure the register number is in range. */
- if (reg < 0 || reg > 0xffff)
- error (_("GDB bug: ax-general.c (ax_reg): register number out of range"));
- grow_expr (x, 3);
- x->buf[x->len] = aop_reg;
- x->buf[x->len + 1] = (reg >> 8) & 0xff;
- x->buf[x->len + 2] = (reg) & 0xff;
- x->len += 3;
+ if (reg >= gdbarch_num_regs (x->gdbarch))
+ {
+ /* This is a pseudo-register. */
+ if (!gdbarch_ax_pseudo_register_push_stack_p (x->gdbarch))
+ error (_("'%s' is a pseudo-register; "
+ "GDB cannot yet trace its contents."),
+ user_reg_map_regnum_to_name (x->gdbarch, reg));
+ if (gdbarch_ax_pseudo_register_push_stack (x->gdbarch, x, reg))
+ error (_("Trace '%s' failed."),
+ user_reg_map_regnum_to_name (x->gdbarch, reg));
+ }
+ else
+ {
+ /* Make sure the register number is in range. */
+ if (reg < 0 || reg > 0xffff)
+ error (_("GDB bug: ax-general.c (ax_reg): register number out of range"));
+ grow_expr (x, 3);
+ x->buf[x->len] = aop_reg;
+ x->buf[x->len + 1] = (reg >> 8) & 0xff;
+ x->buf[x->len + 2] = (reg) & 0xff;
+ x->len += 3;
+ }
}
/* Assemble code to operate on a trace state variable. */
@@ -413,23 +429,38 @@ ax_print (struct ui_file *f, struct agent_expr *x)
void
ax_reg_mask (struct agent_expr *ax, int reg)
{
- int byte = reg / 8;
-
- /* Grow the bit mask if necessary. */
- if (byte >= ax->reg_mask_len)
+ if (reg >= gdbarch_num_regs (ax->gdbarch))
{
- /* It's not appropriate to double here. This isn't a
- string buffer. */
- int new_len = byte + 1;
- unsigned char *new_reg_mask = xrealloc (ax->reg_mask,
- new_len * sizeof (ax->reg_mask[0]));
- memset (new_reg_mask + ax->reg_mask_len, 0,
- (new_len - ax->reg_mask_len) * sizeof (ax->reg_mask[0]));
- ax->reg_mask_len = new_len;
- ax->reg_mask = new_reg_mask;
+ /* This is a pseudo-register. */
+ if (!gdbarch_ax_pseudo_register_collect_p (ax->gdbarch))
+ error (_("'%s' is a pseudo-register; "
+ "GDB cannot yet trace its contents."),
+ user_reg_map_regnum_to_name (ax->gdbarch, reg));
+ if (gdbarch_ax_pseudo_register_collect (ax->gdbarch, ax, reg))
+ error (_("Trace '%s' failed."),
+ user_reg_map_regnum_to_name (ax->gdbarch, reg));
+ }
+ else
+ {
+ int byte = reg / 8;
+
+ /* Grow the bit mask if necessary. */
+ if (byte >= ax->reg_mask_len)
+ {
+ /* It's not appropriate to double here. This isn't a
+ string buffer. */
+ int new_len = byte + 1;
+ unsigned char *new_reg_mask = xrealloc (ax->reg_mask,
+ new_len
+ * sizeof (ax->reg_mask[0]));
+ memset (new_reg_mask + ax->reg_mask_len, 0,
+ (new_len - ax->reg_mask_len) * sizeof (ax->reg_mask[0]));
+ ax->reg_mask_len = new_len;
+ ax->reg_mask = new_reg_mask;
+ }
+
+ ax->reg_mask[byte] |= 1 << (reg % 8);
}
-
- ax->reg_mask[byte] |= 1 << (reg % 8);
}
/* Given an agent expression AX, fill in requirements and other descriptive