X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=gdb%2Fdwarf2expr.c;h=e2e106ba849020c1a6f9705fddb346f4366074c7;hb=334cc82d44775325475752b1126a3257b51b2b0c;hp=fdff8eaa851cbf1a48a021d75352c6446be5c7c5;hpb=197e01b6dcd118b70ed3621b62b2ff3fa929d50f;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/dwarf2expr.c b/gdb/dwarf2expr.c index fdff8eaa85..e2e106ba84 100644 --- a/gdb/dwarf2expr.c +++ b/gdb/dwarf2expr.c @@ -1,6 +1,7 @@ /* DWARF 2 Expression Evaluator. - Copyright (C) 2001, 2002, 2003, 2005 Free Software Foundation, Inc. + Copyright (C) 2001, 2002, 2003, 2005, 2007, 2008, 2009 + Free Software Foundation, Inc. Contributed by Daniel Berlin (dan@dberlin.org) @@ -8,7 +9,7 @@ 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, @@ -17,9 +18,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., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. */ + along with this program. If not, see . */ #include "defs.h" #include "symtab.h" @@ -28,11 +27,13 @@ #include "gdbcore.h" #include "elf/dwarf2.h" #include "dwarf2expr.h" +#include "gdb_assert.h" /* Local prototypes. */ static void execute_stack_op (struct dwarf_expr_context *, gdb_byte *, gdb_byte *); +static struct type *unsigned_address_type (int); /* Create a new context for the expression evaluator. */ @@ -46,6 +47,7 @@ new_dwarf_expr_context (void) retval->stack = xmalloc (retval->stack_allocated * sizeof (CORE_ADDR)); retval->num_pieces = 0; retval->pieces = 0; + retval->max_recursion_depth = 0x100; return retval; } @@ -134,7 +136,13 @@ add_piece (struct dwarf_expr_context *ctx, void dwarf_expr_eval (struct dwarf_expr_context *ctx, gdb_byte *addr, size_t len) { + int old_recursion_depth = ctx->recursion_depth; + execute_stack_op (ctx, addr, addr + len); + + /* CTX RECURSION_DEPTH becomes invalid if an exception was thrown here. */ + + gdb_assert (ctx->recursion_depth == old_recursion_depth); } /* Decode the unsigned LEB128 constant at BUF into the variable pointed to @@ -192,31 +200,43 @@ read_sleb128 (gdb_byte *buf, gdb_byte *buf_end, LONGEST * r) return buf; } -/* Read an address from BUF, and verify that it doesn't extend past - BUF_END. The address is returned, and *BYTES_READ is set to the - number of bytes read from BUF. */ +/* Read an address of size ADDR_SIZE from BUF, and verify that it + doesn't extend past BUF_END. */ CORE_ADDR -dwarf2_read_address (gdb_byte *buf, gdb_byte *buf_end, int *bytes_read) +dwarf2_read_address (struct gdbarch *gdbarch, gdb_byte *buf, + gdb_byte *buf_end, int addr_size) { CORE_ADDR result; - if (buf_end - buf < TARGET_ADDR_BIT / TARGET_CHAR_BIT) + if (buf_end - buf < addr_size) error (_("dwarf2_read_address: Corrupted DWARF expression.")); - *bytes_read = TARGET_ADDR_BIT / TARGET_CHAR_BIT; - /* NOTE: cagney/2003-05-22: This extract is assuming that a DWARF 2 - address is always unsigned. That may or may not be true. */ - result = extract_unsigned_integer (buf, TARGET_ADDR_BIT / TARGET_CHAR_BIT); - return result; + /* For most architectures, calling extract_unsigned_integer() alone + is sufficient for extracting an address. However, some + architectures (e.g. MIPS) use signed addresses and using + extract_unsigned_integer() will not produce a correct + result. Make sure we invoke gdbarch_integer_to_address() + for those architectures which require it. + + The use of `unsigned_address_type' in the code below refers to + the type of buf and has no bearing on the signedness of the + address being returned. */ + + if (gdbarch_integer_to_address_p (gdbarch)) + return gdbarch_integer_to_address + (gdbarch, unsigned_address_type (addr_size), buf); + + return extract_unsigned_integer (buf, addr_size); } -/* Return the type of an address, for unsigned arithmetic. */ +/* Return the type of an address of size ADDR_SIZE, + for unsigned arithmetic. */ static struct type * -unsigned_address_type (void) +unsigned_address_type (int addr_size) { - switch (TARGET_ADDR_BIT / TARGET_CHAR_BIT) + switch (addr_size) { case 2: return builtin_type_uint16; @@ -230,12 +250,13 @@ unsigned_address_type (void) } } -/* Return the type of an address, for signed arithmetic. */ +/* Return the type of an address of size ADDR_SIZE, + for signed arithmetic. */ static struct type * -signed_address_type (void) +signed_address_type (int addr_size) { - switch (TARGET_ADDR_BIT / TARGET_CHAR_BIT) + switch (addr_size) { case 2: return builtin_type_int16; @@ -257,6 +278,12 @@ execute_stack_op (struct dwarf_expr_context *ctx, gdb_byte *op_ptr, gdb_byte *op_end) { ctx->in_reg = 0; + ctx->initialized = 1; /* Default is initialized. */ + + if (ctx->recursion_depth > ctx->max_recursion_depth) + error (_("DWARF-2 expression error: Loop detected (%d)."), + ctx->recursion_depth); + ctx->recursion_depth++; while (op_ptr < op_end) { @@ -264,7 +291,6 @@ execute_stack_op (struct dwarf_expr_context *ctx, CORE_ADDR result; ULONGEST uoffset, reg; LONGEST offset; - int bytes_read; switch (op) { @@ -304,8 +330,9 @@ execute_stack_op (struct dwarf_expr_context *ctx, break; case DW_OP_addr: - result = dwarf2_read_address (op_ptr, op_end, &bytes_read); - op_ptr += bytes_read; + result = dwarf2_read_address (ctx->gdbarch, + op_ptr, op_end, ctx->addr_size); + op_ptr += ctx->addr_size; break; case DW_OP_const1u: @@ -383,7 +410,9 @@ execute_stack_op (struct dwarf_expr_context *ctx, case DW_OP_reg29: case DW_OP_reg30: case DW_OP_reg31: - if (op_ptr != op_end && *op_ptr != DW_OP_piece) + if (op_ptr != op_end + && *op_ptr != DW_OP_piece + && *op_ptr != DW_OP_GNU_uninit) error (_("DWARF-2 expression error: DW_OP_reg operations must be " "used either alone or in conjuction with DW_OP_piece.")); @@ -485,6 +514,20 @@ execute_stack_op (struct dwarf_expr_context *ctx, offset = *op_ptr++; result = dwarf_expr_fetch (ctx, offset); break; + + case DW_OP_swap: + { + CORE_ADDR t1, t2; + + if (ctx->stack_len < 2) + error (_("Not enough elements for DW_OP_swap. Need 2, have %d."), + ctx->stack_len); + t1 = ctx->stack[ctx->stack_len - 1]; + t2 = ctx->stack[ctx->stack_len - 2]; + ctx->stack[ctx->stack_len - 1] = t2; + ctx->stack[ctx->stack_len - 2] = t1; + goto no_push; + } case DW_OP_over: result = dwarf_expr_fetch (ctx, 1); @@ -520,28 +563,22 @@ execute_stack_op (struct dwarf_expr_context *ctx, { case DW_OP_deref: { - gdb_byte *buf = alloca (TARGET_ADDR_BIT / TARGET_CHAR_BIT); - int bytes_read; - - (ctx->read_mem) (ctx->baton, buf, result, - TARGET_ADDR_BIT / TARGET_CHAR_BIT); - result = dwarf2_read_address (buf, - buf + (TARGET_ADDR_BIT - / TARGET_CHAR_BIT), - &bytes_read); + gdb_byte *buf = alloca (ctx->addr_size); + (ctx->read_mem) (ctx->baton, buf, result, ctx->addr_size); + result = dwarf2_read_address (ctx->gdbarch, + buf, buf + ctx->addr_size, + ctx->addr_size); } break; case DW_OP_deref_size: { - gdb_byte *buf = alloca (TARGET_ADDR_BIT / TARGET_CHAR_BIT); - int bytes_read; - - (ctx->read_mem) (ctx->baton, buf, result, *op_ptr++); - result = dwarf2_read_address (buf, - buf + (TARGET_ADDR_BIT - / TARGET_CHAR_BIT), - &bytes_read); + int addr_size = *op_ptr++; + gdb_byte *buf = alloca (addr_size); + (ctx->read_mem) (ctx->baton, buf, result, addr_size); + result = dwarf2_read_address (ctx->gdbarch, + buf, buf + addr_size, + addr_size); } break; @@ -592,8 +629,10 @@ execute_stack_op (struct dwarf_expr_context *ctx, first = dwarf_expr_fetch (ctx, 0); dwarf_expr_pop (ctx); - val1 = value_from_longest (unsigned_address_type (), first); - val2 = value_from_longest (unsigned_address_type (), second); + val1 = value_from_longest + (unsigned_address_type (ctx->addr_size), first); + val2 = value_from_longest + (unsigned_address_type (ctx->addr_size), second); switch (op) { @@ -626,7 +665,8 @@ execute_stack_op (struct dwarf_expr_context *ctx, break; case DW_OP_shra: binop = BINOP_RSH; - val1 = value_from_longest (signed_address_type (), first); + val1 = value_from_longest + (signed_address_type (ctx->addr_size), first); break; case DW_OP_xor: binop = BINOP_BITWISE_XOR; @@ -704,6 +744,14 @@ execute_stack_op (struct dwarf_expr_context *ctx, } goto no_push; + case DW_OP_GNU_uninit: + if (op_ptr != op_end) + error (_("DWARF-2 expression error: DW_OP_GNU_uninit must always " + "be the very last op.")); + + ctx->initialized = 0; + goto no_push; + default: error (_("Unhandled dwarf expression opcode 0x%x"), op); } @@ -712,4 +760,7 @@ execute_stack_op (struct dwarf_expr_context *ctx, dwarf_expr_push (ctx, result); no_push:; } + + ctx->recursion_depth--; + gdb_assert (ctx->recursion_depth >= 0); }