forked from Imagelibrary/binutils-gdb
2010-04-23 Stan Shebs <stan@codesourcery.com>
* ax.h (struct agent_expr): Merge in agent_reqs fields, add some comments. (struct agent_reqs): Remove. (ax_reg_mask): Declare. * ax-general.c (new_agent_expr): Add gdbarch argument, set new fields. (free_agent_expr): Free reg_mask. (ax_print): Add scope and register mask info. (ax_reqs): Remove agent_reqs argument, use agent expression fields, and move part of register mask computation to... (ax_reg_mask): New function. * ax-gdb.c (gen_trace_static_fields): Call it. (gen_traced_pop): Ditto. (is_nontrivial_conversion): Add dummy gdbarch to new_agent_expr. (gen_trace_for_var): Pass gdbarch to new_agent_expr. (gen_trace_for_expr): Ditto, and clear optimized_out flag. (gen_eval_for_expr): Ditto, and require an rvalue. (agent_command): Call ax_reqs. (agent_eval_command): Ditto. * tracepoint.c (report_agent_reqs_errors): Use agent expression fields. (validate_action_line): Ditto. (collect_symbol): Ditto. (encode_actions_1): Ditto.
This commit is contained in:
114
gdb/ax-general.c
114
gdb/ax-general.c
@@ -40,15 +40,23 @@ static void generic_ext (struct agent_expr *x, enum agent_op op, int n);
|
||||
|
||||
/* Allocate a new, empty agent expression. */
|
||||
struct agent_expr *
|
||||
new_agent_expr (CORE_ADDR scope)
|
||||
new_agent_expr (struct gdbarch *gdbarch, CORE_ADDR scope)
|
||||
{
|
||||
struct agent_expr *x = xmalloc (sizeof (*x));
|
||||
|
||||
x->len = 0;
|
||||
x->size = 1; /* Change this to a larger value once
|
||||
reallocation code is tested. */
|
||||
x->buf = xmalloc (x->size);
|
||||
|
||||
x->gdbarch = gdbarch;
|
||||
x->scope = scope;
|
||||
|
||||
/* Bit vector for registers used. */
|
||||
x->reg_mask_len = 1;
|
||||
x->reg_mask = xmalloc (x->reg_mask_len * sizeof (x->reg_mask[0]));
|
||||
memset (x->reg_mask, 0, x->reg_mask_len * sizeof (x->reg_mask[0]));
|
||||
|
||||
return x;
|
||||
}
|
||||
|
||||
@@ -57,6 +65,7 @@ void
|
||||
free_agent_expr (struct agent_expr *x)
|
||||
{
|
||||
xfree (x->buf);
|
||||
xfree (x->reg_mask);
|
||||
xfree (x);
|
||||
}
|
||||
|
||||
@@ -355,6 +364,12 @@ ax_print (struct ui_file *f, struct agent_expr *x)
|
||||
int i;
|
||||
int is_float = 0;
|
||||
|
||||
fprintf_filtered (f, _("Scope: %s\n"), paddress (x->gdbarch, x->scope));
|
||||
fprintf_filtered (f, _("Reg mask:"));
|
||||
for (i = 0; i < x->reg_mask_len; ++i)
|
||||
fprintf_filtered (f, _(" %02x"), x->reg_mask[i]);
|
||||
fprintf_filtered (f, _("\n"));
|
||||
|
||||
/* Check the size of the name array against the number of entries in
|
||||
the enum, to catch additions that people didn't sync. */
|
||||
if ((sizeof (aop_map) / sizeof (aop_map[0]))
|
||||
@@ -394,19 +409,37 @@ ax_print (struct ui_file *f, struct agent_expr *x)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Given an agent expression AX, fill in an agent_reqs structure REQS
|
||||
describing it. */
|
||||
/* Add register REG to the register mask for expression AX. */
|
||||
void
|
||||
ax_reqs (struct agent_expr *ax, struct agent_reqs *reqs)
|
||||
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)
|
||||
{
|
||||
/* 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
|
||||
bits. */
|
||||
void
|
||||
ax_reqs (struct agent_expr *ax)
|
||||
{
|
||||
int i;
|
||||
int height;
|
||||
|
||||
/* Bit vector for registers used. */
|
||||
int reg_mask_len = 1;
|
||||
unsigned char *reg_mask = xmalloc (reg_mask_len * sizeof (reg_mask[0]));
|
||||
|
||||
/* Jump target table. targets[i] is non-zero iff we have found a
|
||||
jump to offset i. */
|
||||
char *targets = (char *) alloca (ax->len * sizeof (targets[0]));
|
||||
@@ -423,20 +456,18 @@ ax_reqs (struct agent_expr *ax, struct agent_reqs *reqs)
|
||||
/* Pointer to a description of the present op. */
|
||||
struct aop_map *op;
|
||||
|
||||
memset (reg_mask, 0, reg_mask_len * sizeof (reg_mask[0]));
|
||||
memset (targets, 0, ax->len * sizeof (targets[0]));
|
||||
memset (boundary, 0, ax->len * sizeof (boundary[0]));
|
||||
|
||||
reqs->max_height = reqs->min_height = height = 0;
|
||||
reqs->flaw = agent_flaw_none;
|
||||
reqs->max_data_size = 0;
|
||||
ax->max_height = ax->min_height = height = 0;
|
||||
ax->flaw = agent_flaw_none;
|
||||
ax->max_data_size = 0;
|
||||
|
||||
for (i = 0; i < ax->len; i += 1 + op->op_size)
|
||||
{
|
||||
if (ax->buf[i] > (sizeof (aop_map) / sizeof (aop_map[0])))
|
||||
{
|
||||
reqs->flaw = agent_flaw_bad_instruction;
|
||||
xfree (reg_mask);
|
||||
ax->flaw = agent_flaw_bad_instruction;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -444,15 +475,13 @@ ax_reqs (struct agent_expr *ax, struct agent_reqs *reqs)
|
||||
|
||||
if (!op->name)
|
||||
{
|
||||
reqs->flaw = agent_flaw_bad_instruction;
|
||||
xfree (reg_mask);
|
||||
ax->flaw = agent_flaw_bad_instruction;
|
||||
return;
|
||||
}
|
||||
|
||||
if (i + 1 + op->op_size > ax->len)
|
||||
{
|
||||
reqs->flaw = agent_flaw_incomplete_instruction;
|
||||
xfree (reg_mask);
|
||||
ax->flaw = agent_flaw_incomplete_instruction;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -461,8 +490,7 @@ ax_reqs (struct agent_expr *ax, struct agent_reqs *reqs)
|
||||
source? */
|
||||
if (targets[i] && (heights[i] != height))
|
||||
{
|
||||
reqs->flaw = agent_flaw_height_mismatch;
|
||||
xfree (reg_mask);
|
||||
ax->flaw = agent_flaw_height_mismatch;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -470,14 +498,14 @@ ax_reqs (struct agent_expr *ax, struct agent_reqs *reqs)
|
||||
heights[i] = height;
|
||||
|
||||
height -= op->consumed;
|
||||
if (height < reqs->min_height)
|
||||
reqs->min_height = height;
|
||||
if (height < ax->min_height)
|
||||
ax->min_height = height;
|
||||
height += op->produced;
|
||||
if (height > reqs->max_height)
|
||||
reqs->max_height = height;
|
||||
if (height > ax->max_height)
|
||||
ax->max_height = height;
|
||||
|
||||
if (op->data_size > reqs->max_data_size)
|
||||
reqs->max_data_size = op->data_size;
|
||||
if (op->data_size > ax->max_data_size)
|
||||
ax->max_data_size = op->data_size;
|
||||
|
||||
/* For jump instructions, check that the target is a valid
|
||||
offset. If it is, record the fact that that location is a
|
||||
@@ -488,8 +516,7 @@ ax_reqs (struct agent_expr *ax, struct agent_reqs *reqs)
|
||||
int target = read_const (ax, i + 1, 2);
|
||||
if (target < 0 || target >= ax->len)
|
||||
{
|
||||
reqs->flaw = agent_flaw_bad_jump;
|
||||
xfree (reg_mask);
|
||||
ax->flaw = agent_flaw_bad_jump;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -499,8 +526,7 @@ ax_reqs (struct agent_expr *ax, struct agent_reqs *reqs)
|
||||
{
|
||||
if (heights[target] != height)
|
||||
{
|
||||
reqs->flaw = agent_flaw_height_mismatch;
|
||||
xfree (reg_mask);
|
||||
ax->flaw = agent_flaw_height_mismatch;
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -517,8 +543,7 @@ ax_reqs (struct agent_expr *ax, struct agent_reqs *reqs)
|
||||
{
|
||||
if (!targets[i + 3])
|
||||
{
|
||||
reqs->flaw = agent_flaw_hole;
|
||||
xfree (reg_mask);
|
||||
ax->flaw = agent_flaw_hole;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -529,22 +554,8 @@ ax_reqs (struct agent_expr *ax, struct agent_reqs *reqs)
|
||||
if (aop_reg == op - aop_map)
|
||||
{
|
||||
int reg = read_const (ax, i + 1, 2);
|
||||
int byte = reg / 8;
|
||||
|
||||
/* Grow the bit mask if necessary. */
|
||||
if (byte >= reg_mask_len)
|
||||
{
|
||||
/* It's not appropriate to double here. This isn't a
|
||||
string buffer. */
|
||||
int new_len = byte + 1;
|
||||
reg_mask = xrealloc (reg_mask,
|
||||
new_len * sizeof (reg_mask[0]));
|
||||
memset (reg_mask + reg_mask_len, 0,
|
||||
(new_len - reg_mask_len) * sizeof (reg_mask[0]));
|
||||
reg_mask_len = new_len;
|
||||
}
|
||||
|
||||
reg_mask[byte] |= 1 << (reg % 8);
|
||||
ax_reg_mask (ax, reg);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -552,12 +563,9 @@ ax_reqs (struct agent_expr *ax, struct agent_reqs *reqs)
|
||||
for (i = 0; i < ax->len; i++)
|
||||
if (targets[i] && !boundary[i])
|
||||
{
|
||||
reqs->flaw = agent_flaw_bad_jump;
|
||||
xfree (reg_mask);
|
||||
ax->flaw = agent_flaw_bad_jump;
|
||||
return;
|
||||
}
|
||||
|
||||
reqs->final_height = height;
|
||||
reqs->reg_mask_len = reg_mask_len;
|
||||
reqs->reg_mask = reg_mask;
|
||||
ax->final_height = height;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user