diff options
author | Hui Zhu <teawater@gmail.com> | 2010-12-28 16:00:13 +0000 |
---|---|---|
committer | Hui Zhu <teawater@gmail.com> | 2010-12-28 16:00:13 +0000 |
commit | 175ff332d0cbd9e522a396be6a990d20fdd0ea07 (patch) | |
tree | 0d2a59ecdf58e2168c518d64a28b39c9508cf699 /gdb/ax-general.c | |
parent | f32bf4a4c92412ee5bed6eb3c45cd2733d2465cc (diff) | |
download | gdb-175ff332d0cbd9e522a396be6a990d20fdd0ea07.zip gdb-175ff332d0cbd9e522a396be6a990d20fdd0ea07.tar.gz gdb-175ff332d0cbd9e522a396be6a990d20fdd0ea07.tar.bz2 |
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.c | 77 |
1 files changed, 54 insertions, 23 deletions
diff --git a/gdb/ax-general.c b/gdb/ax-general.c index ab4591f..e1269e6 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 |