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.
This commit is contained in:
Hui Zhu 2010-12-28 16:00:13 +00:00
parent f32bf4a4c9
commit 175ff332d0
7 changed files with 213 additions and 26 deletions

View file

@ -1,3 +1,19 @@
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.
2010-12-28 Yao Qi <yao@codesourcery.com>
* arm-tdep.c (arm_register_aliases): Remove sp, pc, and fp.

View file

@ -1978,10 +1978,6 @@ gen_expr (struct expression *exp, union exp_element **pc,
if (reg == -1)
internal_error (__FILE__, __LINE__,
_("Register $%s not available"), name);
if (reg >= gdbarch_num_regs (exp->gdbarch))
error (_("'%s' is a pseudo-register; "
"GDB cannot yet trace pseudoregister contents."),
name);
value->kind = axs_lvalue_register;
value->u.reg = reg;
value->type = register_type (exp->gdbarch, reg);

View file

@ -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;
ax->reg_mask[byte] |= 1 << (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);
}
}
/* Given an agent expression AX, fill in requirements and other descriptive

View file

@ -164,6 +164,8 @@ struct gdbarch
gdbarch_pseudo_register_write_ftype *pseudo_register_write;
int num_regs;
int num_pseudo_regs;
gdbarch_ax_pseudo_register_collect_ftype *ax_pseudo_register_collect;
gdbarch_ax_pseudo_register_push_stack_ftype *ax_pseudo_register_push_stack;
int sp_regnum;
int pc_regnum;
int ps_regnum;
@ -314,6 +316,8 @@ struct gdbarch startup_gdbarch =
0, /* pseudo_register_write */
0, /* num_regs */
0, /* num_pseudo_regs */
0, /* ax_pseudo_register_collect */
0, /* ax_pseudo_register_push_stack */
-1, /* sp_regnum */
-1, /* pc_regnum */
-1, /* ps_regnum */
@ -594,6 +598,8 @@ verify_gdbarch (struct gdbarch *gdbarch)
if (gdbarch->num_regs == -1)
fprintf_unfiltered (log, "\n\tnum_regs");
/* Skip verify of num_pseudo_regs, invalid_p == 0 */
/* Skip verify of ax_pseudo_register_collect, has predicate */
/* Skip verify of ax_pseudo_register_push_stack, has predicate */
/* Skip verify of sp_regnum, invalid_p == 0 */
/* Skip verify of pc_regnum, invalid_p == 0 */
/* Skip verify of ps_regnum, invalid_p == 0 */
@ -760,6 +766,18 @@ gdbarch_dump (struct gdbarch *gdbarch, struct ui_file *file)
fprintf_unfiltered (file,
"gdbarch_dump: auto_wide_charset = <%s>\n",
host_address_to_string (gdbarch->auto_wide_charset));
fprintf_unfiltered (file,
"gdbarch_dump: gdbarch_ax_pseudo_register_collect_p() = %d\n",
gdbarch_ax_pseudo_register_collect_p (gdbarch));
fprintf_unfiltered (file,
"gdbarch_dump: ax_pseudo_register_collect = <%s>\n",
host_address_to_string (gdbarch->ax_pseudo_register_collect));
fprintf_unfiltered (file,
"gdbarch_dump: gdbarch_ax_pseudo_register_push_stack_p() = %d\n",
gdbarch_ax_pseudo_register_push_stack_p (gdbarch));
fprintf_unfiltered (file,
"gdbarch_dump: ax_pseudo_register_push_stack = <%s>\n",
host_address_to_string (gdbarch->ax_pseudo_register_push_stack));
fprintf_unfiltered (file,
"gdbarch_dump: believe_pcc_promotion = %s\n",
plongest (gdbarch->believe_pcc_promotion));
@ -1740,6 +1758,54 @@ set_gdbarch_num_pseudo_regs (struct gdbarch *gdbarch,
gdbarch->num_pseudo_regs = num_pseudo_regs;
}
int
gdbarch_ax_pseudo_register_collect_p (struct gdbarch *gdbarch)
{
gdb_assert (gdbarch != NULL);
return gdbarch->ax_pseudo_register_collect != NULL;
}
int
gdbarch_ax_pseudo_register_collect (struct gdbarch *gdbarch, struct agent_expr *ax, int reg)
{
gdb_assert (gdbarch != NULL);
gdb_assert (gdbarch->ax_pseudo_register_collect != NULL);
if (gdbarch_debug >= 2)
fprintf_unfiltered (gdb_stdlog, "gdbarch_ax_pseudo_register_collect called\n");
return gdbarch->ax_pseudo_register_collect (gdbarch, ax, reg);
}
void
set_gdbarch_ax_pseudo_register_collect (struct gdbarch *gdbarch,
gdbarch_ax_pseudo_register_collect_ftype ax_pseudo_register_collect)
{
gdbarch->ax_pseudo_register_collect = ax_pseudo_register_collect;
}
int
gdbarch_ax_pseudo_register_push_stack_p (struct gdbarch *gdbarch)
{
gdb_assert (gdbarch != NULL);
return gdbarch->ax_pseudo_register_push_stack != NULL;
}
int
gdbarch_ax_pseudo_register_push_stack (struct gdbarch *gdbarch, struct agent_expr *ax, int reg)
{
gdb_assert (gdbarch != NULL);
gdb_assert (gdbarch->ax_pseudo_register_push_stack != NULL);
if (gdbarch_debug >= 2)
fprintf_unfiltered (gdb_stdlog, "gdbarch_ax_pseudo_register_push_stack called\n");
return gdbarch->ax_pseudo_register_push_stack (gdbarch, ax, reg);
}
void
set_gdbarch_ax_pseudo_register_push_stack (struct gdbarch *gdbarch,
gdbarch_ax_pseudo_register_push_stack_ftype ax_pseudo_register_push_stack)
{
gdbarch->ax_pseudo_register_push_stack = ax_pseudo_register_push_stack;
}
int
gdbarch_sp_regnum (struct gdbarch *gdbarch)
{

View file

@ -53,6 +53,7 @@ struct target_desc;
struct displaced_step_closure;
struct core_regset_section;
struct syscall;
struct agent_expr;
/* The architecture associated with the connection to the target.
@ -232,6 +233,25 @@ extern void set_gdbarch_num_regs (struct gdbarch *gdbarch, int num_regs);
extern int gdbarch_num_pseudo_regs (struct gdbarch *gdbarch);
extern void set_gdbarch_num_pseudo_regs (struct gdbarch *gdbarch, int num_pseudo_regs);
/* Assemble agent expression bytecode to collect pseudo-register REG.
Return -1 if something goes wrong, 0 otherwise. */
extern int gdbarch_ax_pseudo_register_collect_p (struct gdbarch *gdbarch);
typedef int (gdbarch_ax_pseudo_register_collect_ftype) (struct gdbarch *gdbarch, struct agent_expr *ax, int reg);
extern int gdbarch_ax_pseudo_register_collect (struct gdbarch *gdbarch, struct agent_expr *ax, int reg);
extern void set_gdbarch_ax_pseudo_register_collect (struct gdbarch *gdbarch, gdbarch_ax_pseudo_register_collect_ftype *ax_pseudo_register_collect);
/* Assemble agent expression bytecode to push the value of pseudo-register
REG on the interpreter stack.
Return -1 if something goes wrong, 0 otherwise. */
extern int gdbarch_ax_pseudo_register_push_stack_p (struct gdbarch *gdbarch);
typedef int (gdbarch_ax_pseudo_register_push_stack_ftype) (struct gdbarch *gdbarch, struct agent_expr *ax, int reg);
extern int gdbarch_ax_pseudo_register_push_stack (struct gdbarch *gdbarch, struct agent_expr *ax, int reg);
extern void set_gdbarch_ax_pseudo_register_push_stack (struct gdbarch *gdbarch, gdbarch_ax_pseudo_register_push_stack_ftype *ax_pseudo_register_push_stack);
/* GDB's standard (or well known) register numbers. These can map onto
a real register or a pseudo (computed) register or not be defined at
all (-1).

View file

@ -427,6 +427,15 @@ v:int:num_regs:::0:-1
# combinations of other registers, or they may be computed by GDB.
v:int:num_pseudo_regs:::0:0::0
# Assemble agent expression bytecode to collect pseudo-register REG.
# Return -1 if something goes wrong, 0 otherwise.
M:int:ax_pseudo_register_collect:struct agent_expr *ax, int reg:ax, reg
# Assemble agent expression bytecode to push the value of pseudo-register
# REG on the interpreter stack.
# Return -1 if something goes wrong, 0 otherwise.
M:int:ax_pseudo_register_push_stack:struct agent_expr *ax, int reg:ax, reg
# GDB's standard (or well known) register numbers. These can map onto
# a real register or a pseudo (computed) register or not be defined at
# all (-1).
@ -919,6 +928,7 @@ struct target_desc;
struct displaced_step_closure;
struct core_regset_section;
struct syscall;
struct agent_expr;
/* The architecture associated with the connection to the target.

View file

@ -58,6 +58,7 @@
#include "dwarf2-frame.h"
#include "user-regs.h"
#include "valprint.h"
#include "ax.h"
static const struct objfile_data *mips_pdr_data;
@ -616,6 +617,48 @@ mips_pseudo_register_write (struct gdbarch *gdbarch,
internal_error (__FILE__, __LINE__, _("bad register size"));
}
static int
mips_ax_pseudo_register_collect (struct gdbarch *gdbarch,
struct agent_expr *ax, int reg)
{
int rawnum = reg % gdbarch_num_regs (gdbarch);
gdb_assert (reg >= gdbarch_num_regs (gdbarch)
&& reg < 2 * gdbarch_num_regs (gdbarch));
ax_reg_mask (ax, rawnum);
return 0;
}
static int
mips_ax_pseudo_register_push_stack (struct gdbarch *gdbarch,
struct agent_expr *ax, int reg)
{
int rawnum = reg % gdbarch_num_regs (gdbarch);
gdb_assert (reg >= gdbarch_num_regs (gdbarch)
&& reg < 2 * gdbarch_num_regs (gdbarch));
if (register_size (gdbarch, rawnum) >= register_size (gdbarch, reg))
{
ax_reg (ax, rawnum);
if (register_size (gdbarch, rawnum) > register_size (gdbarch, reg))
{
if (!gdbarch_tdep (gdbarch)->mips64_transfers_32bit_regs_p
|| gdbarch_byte_order (gdbarch) != BFD_ENDIAN_BIG)
{
ax_const_l (ax, 32);
ax_simple (ax, aop_lsh);
}
ax_const_l (ax, 32);
ax_simple (ax, aop_rsh_signed);
}
}
else
internal_error (__FILE__, __LINE__, _("bad register size"));
return 0;
}
/* Table to translate MIPS16 register field to actual register number. */
static int mips16_to_32_reg[8] = { 16, 17, 2, 3, 4, 5, 6, 7 };
@ -5933,6 +5976,11 @@ mips_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
set_gdbarch_pseudo_register_read (gdbarch, mips_pseudo_register_read);
set_gdbarch_pseudo_register_write (gdbarch, mips_pseudo_register_write);
set_gdbarch_ax_pseudo_register_collect (gdbarch,
mips_ax_pseudo_register_collect);
set_gdbarch_ax_pseudo_register_push_stack
(gdbarch, mips_ax_pseudo_register_push_stack);
set_gdbarch_elf_make_msymbol_special (gdbarch,
mips_elf_make_msymbol_special);