/* Functions for manipulating expressions designed to be executed on the agent
- Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc.
+ Copyright (C) 1998, 1999, 2000, 2007, 2008, 2009, 2010
+ Free Software Foundation, Inc.
This file is part of GDB.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
+ the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin Street, Fifth Floor,
- Boston, MA 02110-1301, USA. */
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
/* Despite what the above comment says about this file being part of
GDB, we would like to keep these functions free of GDB
/* 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;
}
free_agent_expr (struct agent_expr *x)
{
xfree (x->buf);
+ xfree (x->reg_mask);
xfree (x);
}
use the shortest representation. */
for (op = 0, size = 8; size < 64; size *= 2, op++)
{
- LONGEST lim = 1 << (size - 1);
+ LONGEST lim = ((LONGEST) 1) << (size - 1);
if (-lim <= l && l <= lim - 1)
break;
x->buf[x->len + 2] = (reg) & 0xff;
x->len += 3;
}
+
+/* Assemble code to operate on a trace state variable. */
+
+void
+ax_tsv (struct agent_expr *x, enum agent_op op, int num)
+{
+ /* Make sure the tsv number is in range. */
+ if (num < 0 || num > 0xffff)
+ internal_error (__FILE__, __LINE__, _("ax-general.c (ax_tsv): variable number is %d, out of range"), num);
+
+ grow_expr (x, 3);
+ x->buf[x->len] = op;
+ x->buf[x->len + 1] = (num >> 8) & 0xff;
+ x->buf[x->len + 2] = (num) & 0xff;
+ x->len += 3;
+}
\f
{"pop", 0, 0, 1, 0}, /* 0x29 */
{"zero_ext", 1, 0, 1, 1}, /* 0x2a */
{"swap", 0, 0, 2, 2}, /* 0x2b */
- {0, 0, 0, 0, 0}, /* 0x2c */
- {0, 0, 0, 0, 0}, /* 0x2d */
- {0, 0, 0, 0, 0}, /* 0x2e */
+ {"getv", 2, 0, 0, 1}, /* 0x2c */
+ {"setv", 2, 0, 0, 1}, /* 0x2d */
+ {"tracev", 2, 0, 0, 1}, /* 0x2e */
{0, 0, 0, 0, 0}, /* 0x2f */
{"trace16", 2, 0, 1, 1}, /* 0x30 */
};
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]))
}
}
+/* Add register REG to the register mask for expression AX. */
+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)
+ {
+ /* 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 an agent_reqs structure REQS
- describing it. */
+/* Given an agent expression AX, fill in requirements and other descriptive
+ bits. */
void
-ax_reqs (struct agent_expr *ax, struct agent_reqs *reqs)
+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]));
/* 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;
}
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;
}
source? */
if (targets[i] && (heights[i] != height))
{
- reqs->flaw = agent_flaw_height_mismatch;
- xfree (reg_mask);
+ ax->flaw = agent_flaw_height_mismatch;
return;
}
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
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;
}
{
if (heights[target] != height)
{
- reqs->flaw = agent_flaw_height_mismatch;
- xfree (reg_mask);
+ ax->flaw = agent_flaw_height_mismatch;
return;
}
}
{
if (!targets[i + 3])
{
- reqs->flaw = agent_flaw_hole;
- xfree (reg_mask);
+ ax->flaw = agent_flaw_hole;
return;
}
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);
}
}
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;
}