X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=gdb%2Fax-general.c;h=ab4591fa0886210f70870a3fadef716da96ba2d5;hb=35c9c7ba77c07c52aa0c81e62919bb3984b86c3a;hp=eb7a7caa11ebc02a6d19f645682c6fc0e42a4d11;hpb=3d263c1d0a2f82fcf209a00e029b32ac8cf8f838;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/ax-general.c b/gdb/ax-general.c index eb7a7caa11..ab4591fa08 100644 --- a/gdb/ax-general.c +++ b/gdb/ax-general.c @@ -1,11 +1,12 @@ /* Functions for manipulating expressions designed to be executed on the agent - Copyright 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, @@ -14,9 +15,7 @@ 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., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ + along with this program. If not, see . */ /* Despite what the above comment says about this file being part of GDB, we would like to keep these functions free of GDB @@ -41,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; } @@ -58,6 +65,7 @@ void free_agent_expr (struct agent_expr *x) { xfree (x->buf); + xfree (x->reg_mask); xfree (x); } @@ -231,8 +239,12 @@ ax_const_l (struct agent_expr *x, LONGEST l) signed or unsigned; we always reproduce the value exactly, and use the shortest representation. */ for (op = 0, size = 8; size < 64; size *= 2, op++) - if (-((LONGEST) 1 << size) <= l && l < ((LONGEST) 1 << size)) - break; + { + LONGEST lim = ((LONGEST) 1) << (size - 1); + + if (-lim <= l && l <= lim - 1) + break; + } /* Emit the right opcode... */ ax_simple (x, ops[op]); @@ -269,6 +281,22 @@ ax_reg (struct agent_expr *x, int reg) 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; +} @@ -321,9 +349,9 @@ struct aop_map aop_map[] = {"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 */ }; @@ -336,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])) @@ -375,28 +409,46 @@ ax_print (struct ui_file *f, struct agent_expr *x) } } +/* 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 there is a jump to - offset i. */ + /* 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])); - /* Instruction boundary table. boundary[i] is non-zero iff an - instruction starts at offset i. */ + /* Instruction boundary table. boundary[i] is non-zero iff our scan + has reached an instruction starting at offset i. */ char *boundary = (char *) alloca (ax->len * sizeof (boundary[0])); - /* Stack height record. iff either targets[i] or boundary[i] is + /* Stack height record. If either targets[i] or boundary[i] is non-zero, heights[i] is the height the stack should have before executing the bytecode at that point. */ int *heights = (int *) alloca (ax->len * sizeof (heights[0])); @@ -404,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; } @@ -425,24 +475,22 @@ 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; } - /* If this instruction is a jump target, does the current stack - height match the stack height at the jump source? */ + /* If this instruction is a forward jump target, does the + current stack height match the stack height at the jump + source? */ if (targets[i] && (heights[i] != height)) { - reqs->flaw = agent_flaw_height_mismatch; - xfree (reg_mask); + ax->flaw = agent_flaw_height_mismatch; return; } @@ -450,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 @@ -468,25 +516,24 @@ 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; } - /* Have we already found other jumps to the same location? */ - else if (targets[target]) + + /* Do we have any information about what the stack height + should be at the target? */ + if (targets[target] || boundary[target]) { - if (heights[i] != height) + if (heights[target] != height) { - reqs->flaw = agent_flaw_height_mismatch; - xfree (reg_mask); + ax->flaw = agent_flaw_height_mismatch; return; } } - else - { - targets[target] = 1; - heights[target] = height; - } + + /* Record the target, along with the stack height we expect. */ + targets[target] = 1; + heights[target] = height; } /* For unconditional jumps with a successor, check that the @@ -496,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; } @@ -508,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); } } @@ -531,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; }