X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=gdb%2Fax-general.c;h=30f90e897120d1d4a6c9818ddca8e2bd5046d342;hb=2ba163c8d19971010e22176cf688b3de80bd8f08;hp=27bc32a8293776c8699ac0af5145f3992df00667;hpb=7b6bb8daaceb9ecf3f42dea57ae82733d6a3b2f6;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/ax-general.c b/gdb/ax-general.c index 27bc32a829..30f90e8971 100644 --- a/gdb/ax-general.c +++ b/gdb/ax-general.c @@ -1,6 +1,5 @@ /* Functions for manipulating expressions designed to be executed on the agent - Copyright (C) 1998, 1999, 2000, 2007, 2008, 2009, 2010, 2011 - Free Software Foundation, Inc. + Copyright (C) 1998-2016 Free Software Foundation, Inc. This file is part of GDB. @@ -26,8 +25,6 @@ #include "ax.h" #include "value.h" -#include "gdb_string.h" - #include "user-regs.h" static void grow_expr (struct agent_expr *x, int n); @@ -44,20 +41,22 @@ static void generic_ext (struct agent_expr *x, enum agent_op op, int n); struct agent_expr * new_agent_expr (struct gdbarch *gdbarch, CORE_ADDR scope) { - struct agent_expr *x = xmalloc (sizeof (*x)); + struct agent_expr *x = XNEW (struct agent_expr); x->len = 0; x->size = 1; /* Change this to a larger value once reallocation code is tested. */ - x->buf = xmalloc (x->size); + x->buf = (unsigned char *) 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])); + x->reg_mask = XCNEWVEC (unsigned char, x->reg_mask_len); + + x->tracing = 0; + x->trace_string = 0; return x; } @@ -74,7 +73,7 @@ free_agent_expr (struct agent_expr *x) static void do_free_agent_expr_cleanup (void *x) { - free_agent_expr (x); + free_agent_expr ((struct agent_expr *) x); } struct cleanup * @@ -94,7 +93,7 @@ grow_expr (struct agent_expr *x, int n) x->size *= 2; if (x->size < x->len + n) x->size = x->len + n + 10; - x->buf = xrealloc (x->buf, x->size); + x->buf = (unsigned char *) xrealloc (x->buf, x->size); } } @@ -134,13 +133,32 @@ read_const (struct agent_expr *x, int o, int n) return accum; } +/* See ax.h. */ + +void +ax_raw_byte (struct agent_expr *x, gdb_byte byte) +{ + grow_expr (x, 1); + x->buf[x->len++] = byte; +} /* Append a simple operator OP to EXPR. */ void ax_simple (struct agent_expr *x, enum agent_op op) { - grow_expr (x, 1); - x->buf[x->len++] = op; + ax_raw_byte (x, op); +} + +/* Append a pick operator to EXPR. DEPTH is the stack item to pick, + with 0 being top of stack. */ + +void +ax_pick (struct agent_expr *x, int depth) +{ + if (depth < 0 || depth > 255) + error (_("GDB bug: ax-general.c (ax_pick): stack depth out of range")); + ax_simple (x, aop_pick); + append_const (x, 1, depth); } @@ -154,7 +172,8 @@ generic_ext (struct agent_expr *x, enum agent_op op, int n) error (_("GDB bug: ax-general.c (generic_ext): bit count out of range")); /* That had better be enough range. */ if (sizeof (LONGEST) * 8 > 255) - error (_("GDB bug: ax-general.c (generic_ext): opcode has inadequate range")); + error (_("GDB bug: ax-general.c (generic_ext): " + "opcode has inadequate range")); grow_expr (x, 2); x->buf[x->len++] = op; @@ -184,7 +203,8 @@ ax_trace_quick (struct agent_expr *x, int n) { /* N must fit in a byte. */ if (n < 0 || n > 255) - error (_("GDB bug: ax-general.c (ax_trace_quick): size out of range for trace_quick")); + error (_("GDB bug: ax-general.c (ax_trace_quick): " + "size out of range for trace_quick")); grow_expr (x, 2); x->buf[x->len++] = aop_trace_quick; @@ -265,7 +285,8 @@ void ax_const_d (struct agent_expr *x, LONGEST d) { /* FIXME: floating-point support not present yet. */ - error (_("GDB bug: ax-general.c (ax_const_d): floating point not supported yet")); + error (_("GDB bug: ax-general.c (ax_const_d): " + "floating point not supported yet")); } @@ -289,7 +310,8 @@ 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")); + 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; @@ -305,7 +327,9 @@ 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); + 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; @@ -313,6 +337,30 @@ ax_tsv (struct agent_expr *x, enum agent_op op, int num) x->buf[x->len + 2] = (num) & 0xff; x->len += 3; } + +/* Append a string to the expression. Note that the string is going + into the bytecodes directly, not on the stack. As a precaution, + include both length as prefix, and terminate with a NUL. (The NUL + is counted in the length.) */ + +void +ax_string (struct agent_expr *x, const char *str, int slen) +{ + int i; + + /* Make sure the string length is reasonable. */ + if (slen < 0 || slen > 0xffff) + internal_error (__FILE__, __LINE__, + _("ax-general.c (ax_string): string " + "length is %d, out of allowed range"), slen); + + grow_expr (x, 2 + slen + 1); + x->buf[x->len++] = ((slen + 1) >> 8) & 0xff; + x->buf[x->len++] = (slen + 1) & 0xff; + for (i = 0; i < slen; ++i) + x->buf[x->len++] = str[i]; + x->buf[x->len++] = '\0'; +} @@ -321,55 +369,11 @@ ax_tsv (struct agent_expr *x, enum agent_op op, int num) struct aop_map aop_map[] = { - {0, 0, 0, 0, 0}, - {"float", 0, 0, 0, 0}, /* 0x01 */ - {"add", 0, 0, 2, 1}, /* 0x02 */ - {"sub", 0, 0, 2, 1}, /* 0x03 */ - {"mul", 0, 0, 2, 1}, /* 0x04 */ - {"div_signed", 0, 0, 2, 1}, /* 0x05 */ - {"div_unsigned", 0, 0, 2, 1}, /* 0x06 */ - {"rem_signed", 0, 0, 2, 1}, /* 0x07 */ - {"rem_unsigned", 0, 0, 2, 1}, /* 0x08 */ - {"lsh", 0, 0, 2, 1}, /* 0x09 */ - {"rsh_signed", 0, 0, 2, 1}, /* 0x0a */ - {"rsh_unsigned", 0, 0, 2, 1}, /* 0x0b */ - {"trace", 0, 0, 2, 0}, /* 0x0c */ - {"trace_quick", 1, 0, 1, 1}, /* 0x0d */ - {"log_not", 0, 0, 1, 1}, /* 0x0e */ - {"bit_and", 0, 0, 2, 1}, /* 0x0f */ - {"bit_or", 0, 0, 2, 1}, /* 0x10 */ - {"bit_xor", 0, 0, 2, 1}, /* 0x11 */ - {"bit_not", 0, 0, 1, 1}, /* 0x12 */ - {"equal", 0, 0, 2, 1}, /* 0x13 */ - {"less_signed", 0, 0, 2, 1}, /* 0x14 */ - {"less_unsigned", 0, 0, 2, 1}, /* 0x15 */ - {"ext", 1, 0, 1, 1}, /* 0x16 */ - {"ref8", 0, 8, 1, 1}, /* 0x17 */ - {"ref16", 0, 16, 1, 1}, /* 0x18 */ - {"ref32", 0, 32, 1, 1}, /* 0x19 */ - {"ref64", 0, 64, 1, 1}, /* 0x1a */ - {"ref_float", 0, 0, 1, 1}, /* 0x1b */ - {"ref_double", 0, 0, 1, 1}, /* 0x1c */ - {"ref_long_double", 0, 0, 1, 1}, /* 0x1d */ - {"l_to_d", 0, 0, 1, 1}, /* 0x1e */ - {"d_to_l", 0, 0, 1, 1}, /* 0x1f */ - {"if_goto", 2, 0, 1, 0}, /* 0x20 */ - {"goto", 2, 0, 0, 0}, /* 0x21 */ - {"const8", 1, 8, 0, 1}, /* 0x22 */ - {"const16", 2, 16, 0, 1}, /* 0x23 */ - {"const32", 4, 32, 0, 1}, /* 0x24 */ - {"const64", 8, 64, 0, 1}, /* 0x25 */ - {"reg", 2, 0, 0, 1}, /* 0x26 */ - {"end", 0, 0, 0, 0}, /* 0x27 */ - {"dup", 0, 0, 1, 2}, /* 0x28 */ - {"pop", 0, 0, 1, 0}, /* 0x29 */ - {"zero_ext", 1, 0, 1, 1}, /* 0x2a */ - {"swap", 0, 0, 2, 2}, /* 0x2b */ - {"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 */ + {0, 0, 0, 0, 0} +#define DEFOP(NAME, SIZE, DATA_SIZE, CONSUMED, PRODUCED, VALUE) \ + , { # NAME, SIZE, DATA_SIZE, CONSUMED, PRODUCED } +#include "ax.def" +#undef DEFOP }; @@ -378,7 +382,6 @@ void 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:")); @@ -394,7 +397,7 @@ ax_print (struct ui_file *f, struct agent_expr *x) for (i = 0; i < x->len;) { - enum agent_op op = x->buf[i]; + enum agent_op op = (enum agent_op) x->buf[i]; if (op >= (sizeof (aop_map) / sizeof (aop_map[0])) || !aop_map[op].name) @@ -418,10 +421,21 @@ ax_print (struct ui_file *f, struct agent_expr *x) print_longest (f, 'd', 0, read_const (x, i + 1, aop_map[op].op_size)); } + /* Handle the complicated printf arguments specially. */ + else if (op == aop_printf) + { + int slen, nargs; + + i++; + nargs = x->buf[i++]; + slen = x->buf[i++]; + slen = slen * 256 + x->buf[i++]; + fprintf_filtered (f, _(" \"%s\", %d args"), + &(x->buf[i]), nargs); + i += slen - 1; + } fprintf_filtered (f, "\n"); i += 1 + aop_map[op].op_size; - - is_float = (op == aop_float); } } @@ -450,9 +464,9 @@ ax_reg_mask (struct agent_expr *ax, int reg) /* 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])); + unsigned char *new_reg_mask + = XRESIZEVEC (unsigned char, ax->reg_mask, new_len); + 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;