X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=gdb%2Fdwarf2expr.c;h=7bf3c78d86370cf1458c398deedaea9f483f1357;hb=9d78f827e0da9ab6fda2d6ef2d59cebb805b411f;hp=450a57f3a85cfd1bf201d397a8318cf0027d3c14;hpb=82ae4854632a42a7d7d74b6cdb8da9be7890976c;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/dwarf2expr.c b/gdb/dwarf2expr.c index 450a57f3a8..7bf3c78d86 100644 --- a/gdb/dwarf2expr.c +++ b/gdb/dwarf2expr.c @@ -1,7 +1,6 @@ /* DWARF 2 Expression Evaluator. - Copyright (C) 2001, 2002, 2003, 2005, 2007, 2008, 2009, 2010, 2011 - Free Software Foundation, Inc. + Copyright (C) 2001-2016 Free Software Foundation, Inc. Contributed by Daniel Berlin (dan@dberlin.org) @@ -27,13 +26,69 @@ #include "gdbcore.h" #include "dwarf2.h" #include "dwarf2expr.h" -#include "gdb_assert.h" +#include "dwarf2loc.h" /* Local prototypes. */ static void execute_stack_op (struct dwarf_expr_context *, const gdb_byte *, const gdb_byte *); +/* Cookie for gdbarch data. */ + +static struct gdbarch_data *dwarf_arch_cookie; + +/* This holds gdbarch-specific types used by the DWARF expression + evaluator. See comments in execute_stack_op. */ + +struct dwarf_gdbarch_types +{ + struct type *dw_types[3]; +}; + +/* Allocate and fill in dwarf_gdbarch_types for an arch. */ + +static void * +dwarf_gdbarch_types_init (struct gdbarch *gdbarch) +{ + struct dwarf_gdbarch_types *types + = GDBARCH_OBSTACK_ZALLOC (gdbarch, struct dwarf_gdbarch_types); + + /* The types themselves are lazily initialized. */ + + return types; +} + +/* Return the type used for DWARF operations where the type is + unspecified in the DWARF spec. Only certain sizes are + supported. */ + +static struct type * +dwarf_expr_address_type (struct dwarf_expr_context *ctx) +{ + struct dwarf_gdbarch_types *types + = (struct dwarf_gdbarch_types *) gdbarch_data (ctx->gdbarch, + dwarf_arch_cookie); + int ndx; + + if (ctx->addr_size == 2) + ndx = 0; + else if (ctx->addr_size == 4) + ndx = 1; + else if (ctx->addr_size == 8) + ndx = 2; + else + error (_("Unsupported address size in DWARF expressions: %d bits"), + 8 * ctx->addr_size); + + if (types->dw_types[ndx] == NULL) + types->dw_types[ndx] + = arch_integer_type (ctx->gdbarch, + 8 * ctx->addr_size, + 0, ""); + + return types->dw_types[ndx]; +} + /* Create a new context for the expression evaluator. */ struct dwarf_expr_context * @@ -41,11 +96,10 @@ new_dwarf_expr_context (void) { struct dwarf_expr_context *retval; - retval = xcalloc (1, sizeof (struct dwarf_expr_context)); + retval = XCNEW (struct dwarf_expr_context); retval->stack_len = 0; retval->stack_allocated = 10; - retval->stack = xmalloc (retval->stack_allocated - * sizeof (struct dwarf_stack_value)); + retval->stack = XNEWVEC (struct dwarf_stack_value, retval->stack_allocated); retval->num_pieces = 0; retval->pieces = 0; retval->max_recursion_depth = 0x100; @@ -67,7 +121,7 @@ free_dwarf_expr_context (struct dwarf_expr_context *ctx) static void free_dwarf_expr_context_cleanup (void *arg) { - free_dwarf_expr_context (arg); + free_dwarf_expr_context ((struct dwarf_expr_context *) arg); } /* Return a cleanup that calls free_dwarf_expr_context. */ @@ -88,34 +142,39 @@ dwarf_expr_grow_stack (struct dwarf_expr_context *ctx, size_t need) { size_t newlen = ctx->stack_len + need + 10; - ctx->stack = xrealloc (ctx->stack, - newlen * sizeof (struct dwarf_stack_value)); + ctx->stack = XRESIZEVEC (struct dwarf_stack_value, ctx->stack, newlen); ctx->stack_allocated = newlen; } } /* Push VALUE onto CTX's stack. */ -void -dwarf_expr_push (struct dwarf_expr_context *ctx, ULONGEST value, +static void +dwarf_expr_push (struct dwarf_expr_context *ctx, struct value *value, int in_stack_memory) { struct dwarf_stack_value *v; - /* We keep all stack elements within the range defined by the - DWARF address size. */ - if (ctx->addr_size < sizeof (ULONGEST)) - value &= ((ULONGEST) 1 << (ctx->addr_size * HOST_CHAR_BIT)) - 1; - dwarf_expr_grow_stack (ctx, 1); v = &ctx->stack[ctx->stack_len++]; v->value = value; v->in_stack_memory = in_stack_memory; } -/* Pop the top item off of CTX's stack. */ +/* Push VALUE onto CTX's stack. */ void +dwarf_expr_push_address (struct dwarf_expr_context *ctx, CORE_ADDR value, + int in_stack_memory) +{ + dwarf_expr_push (ctx, + value_from_ulongest (dwarf_expr_address_type (ctx), value), + in_stack_memory); +} + +/* Pop the top item off of CTX's stack. */ + +static void dwarf_expr_pop (struct dwarf_expr_context *ctx) { if (ctx->stack_len <= 0) @@ -125,7 +184,7 @@ dwarf_expr_pop (struct dwarf_expr_context *ctx) /* Retrieve the N'th item on CTX's stack. */ -ULONGEST +struct value * dwarf_expr_fetch (struct dwarf_expr_context *ctx, int n) { if (ctx->stack_len <= n) @@ -133,7 +192,61 @@ dwarf_expr_fetch (struct dwarf_expr_context *ctx, int n) "stack only has %d elements on it."), n, ctx->stack_len); return ctx->stack[ctx->stack_len - (1 + n)].value; +} + +/* Require that TYPE be an integral type; throw an exception if not. */ + +static void +dwarf_require_integral (struct type *type) +{ + if (TYPE_CODE (type) != TYPE_CODE_INT + && TYPE_CODE (type) != TYPE_CODE_CHAR + && TYPE_CODE (type) != TYPE_CODE_BOOL) + error (_("integral type expected in DWARF expression")); +} + +/* Return the unsigned form of TYPE. TYPE is necessarily an integral + type. */ +static struct type * +get_unsigned_type (struct gdbarch *gdbarch, struct type *type) +{ + switch (TYPE_LENGTH (type)) + { + case 1: + return builtin_type (gdbarch)->builtin_uint8; + case 2: + return builtin_type (gdbarch)->builtin_uint16; + case 4: + return builtin_type (gdbarch)->builtin_uint32; + case 8: + return builtin_type (gdbarch)->builtin_uint64; + default: + error (_("no unsigned variant found for type, while evaluating " + "DWARF expression")); + } +} + +/* Return the signed form of TYPE. TYPE is necessarily an integral + type. */ + +static struct type * +get_signed_type (struct gdbarch *gdbarch, struct type *type) +{ + switch (TYPE_LENGTH (type)) + { + case 1: + return builtin_type (gdbarch)->builtin_int8; + case 2: + return builtin_type (gdbarch)->builtin_int16; + case 4: + return builtin_type (gdbarch)->builtin_int32; + case 8: + return builtin_type (gdbarch)->builtin_int64; + default: + error (_("no signed variant found for type, while evaluating " + "DWARF expression")); + } } /* Retrieve the N'th item on CTX's stack, converted to an address. */ @@ -141,7 +254,14 @@ dwarf_expr_fetch (struct dwarf_expr_context *ctx, int n) CORE_ADDR dwarf_expr_fetch_address (struct dwarf_expr_context *ctx, int n) { - ULONGEST result = dwarf_expr_fetch (ctx, n); + struct value *result_val = dwarf_expr_fetch (ctx, n); + enum bfd_endian byte_order = gdbarch_byte_order (ctx->gdbarch); + ULONGEST result; + + dwarf_require_integral (value_type (result_val)); + result = extract_unsigned_integer (value_contents (result_val), + TYPE_LENGTH (value_type (result_val)), + byte_order); /* For most architectures, calling extract_unsigned_integer() alone is sufficient for extracting an address. However, some @@ -151,25 +271,9 @@ dwarf_expr_fetch_address (struct dwarf_expr_context *ctx, int n) for those architectures which require it. */ if (gdbarch_integer_to_address_p (ctx->gdbarch)) { - enum bfd_endian byte_order = gdbarch_byte_order (ctx->gdbarch); - gdb_byte *buf = alloca (ctx->addr_size); - struct type *int_type; - - switch (ctx->addr_size) - { - case 2: - int_type = builtin_type (ctx->gdbarch)->builtin_uint16; - break; - case 4: - int_type = builtin_type (ctx->gdbarch)->builtin_uint32; - break; - case 8: - int_type = builtin_type (ctx->gdbarch)->builtin_uint64; - break; - default: - internal_error (__FILE__, __LINE__, - _("Unsupported address size.\n")); - } + gdb_byte *buf = (gdb_byte *) alloca (ctx->addr_size); + struct type *int_type = get_unsigned_type (ctx->gdbarch, + value_type (result_val)); store_unsigned_integer (buf, ctx->addr_size, byte_order, result); return gdbarch_integer_to_address (ctx->gdbarch, int_type, buf); @@ -188,7 +292,6 @@ dwarf_expr_fetch_in_stack_memory (struct dwarf_expr_context *ctx, int n) "stack only has %d elements on it."), n, ctx->stack_len); return ctx->stack[ctx->stack_len - (1 + n)].in_stack_memory; - } /* Return true if the expression stack is empty. */ @@ -207,9 +310,8 @@ add_piece (struct dwarf_expr_context *ctx, ULONGEST size, ULONGEST offset) ctx->num_pieces++; - ctx->pieces = xrealloc (ctx->pieces, - (ctx->num_pieces - * sizeof (struct dwarf_expr_piece))); + ctx->pieces + = XRESIZEVEC (struct dwarf_expr_piece, ctx->pieces, ctx->num_pieces); p = &ctx->pieces[ctx->num_pieces - 1]; p->location = ctx->location; @@ -237,9 +339,11 @@ add_piece (struct dwarf_expr_context *ctx, ULONGEST size, ULONGEST offset) } else if (p->location == DWARF_VALUE_IMPLICIT_POINTER) { - p->v.ptr.die = ctx->len; - p->v.ptr.offset = (LONGEST) dwarf_expr_fetch (ctx, 0); + p->v.ptr.die.sect_off = ctx->len; + p->v.ptr.offset = value_as_long (dwarf_expr_fetch (ctx, 0)); } + else if (p->location == DWARF_VALUE_REGISTER) + p->v.regno = value_as_long (dwarf_expr_fetch (ctx, 0)); else { p->v.value = dwarf_expr_fetch (ctx, 0); @@ -262,58 +366,36 @@ dwarf_expr_eval (struct dwarf_expr_context *ctx, const gdb_byte *addr, gdb_assert (ctx->recursion_depth == old_recursion_depth); } -/* Decode the unsigned LEB128 constant at BUF into the variable pointed to - by R, and return the new value of BUF. Verify that it doesn't extend - past BUF_END. */ +/* Helper to read a uleb128 value or throw an error. */ const gdb_byte * -read_uleb128 (const gdb_byte *buf, const gdb_byte *buf_end, ULONGEST * r) +safe_read_uleb128 (const gdb_byte *buf, const gdb_byte *buf_end, + uint64_t *r) { - unsigned shift = 0; - ULONGEST result = 0; - gdb_byte byte; - - while (1) - { - if (buf >= buf_end) - error (_("read_uleb128: Corrupted DWARF expression.")); - - byte = *buf++; - result |= (byte & 0x7f) << shift; - if ((byte & 0x80) == 0) - break; - shift += 7; - } - *r = result; + buf = gdb_read_uleb128 (buf, buf_end, r); + if (buf == NULL) + error (_("DWARF expression error: ran off end of buffer reading uleb128 value")); return buf; } -/* Decode the signed LEB128 constant at BUF into the variable pointed to - by R, and return the new value of BUF. Verify that it doesn't extend - past BUF_END. */ +/* Helper to read a sleb128 value or throw an error. */ const gdb_byte * -read_sleb128 (const gdb_byte *buf, const gdb_byte *buf_end, LONGEST * r) +safe_read_sleb128 (const gdb_byte *buf, const gdb_byte *buf_end, + int64_t *r) { - unsigned shift = 0; - LONGEST result = 0; - gdb_byte byte; - - while (1) - { - if (buf >= buf_end) - error (_("read_sleb128: Corrupted DWARF expression.")); - - byte = *buf++; - result |= (byte & 0x7f) << shift; - shift += 7; - if ((byte & 0x80) == 0) - break; - } - if (shift < (sizeof (*r) * 8) && (byte & 0x40) != 0) - result |= -(1 << shift); + buf = gdb_read_sleb128 (buf, buf_end, r); + if (buf == NULL) + error (_("DWARF expression error: ran off end of buffer reading sleb128 value")); + return buf; +} - *r = result; +const gdb_byte * +safe_skip_leb128 (const gdb_byte *buf, const gdb_byte *buf_end) +{ + buf = gdb_skip_leb128 (buf, buf_end); + if (buf == NULL) + error (_("DWARF expression error: ran off end of buffer reading leb128 value")); return buf; } @@ -330,11 +412,220 @@ dwarf_expr_require_composition (const gdb_byte *op_ptr, const gdb_byte *op_end, checked at the other place that this function is called. */ if (op_ptr != op_end && *op_ptr != DW_OP_piece && *op_ptr != DW_OP_bit_piece) error (_("DWARF-2 expression error: `%s' operations must be " - "used either alone or in conjuction with DW_OP_piece " + "used either alone or in conjunction with DW_OP_piece " "or DW_OP_bit_piece."), op_name); } +/* Return true iff the types T1 and T2 are "the same". This only does + checks that might reasonably be needed to compare DWARF base + types. */ + +static int +base_types_equal_p (struct type *t1, struct type *t2) +{ + if (TYPE_CODE (t1) != TYPE_CODE (t2)) + return 0; + if (TYPE_UNSIGNED (t1) != TYPE_UNSIGNED (t2)) + return 0; + return TYPE_LENGTH (t1) == TYPE_LENGTH (t2); +} + +/* A convenience function to call get_base_type on CTX and return the + result. DIE is the DIE whose type we need. SIZE is non-zero if + this function should verify that the resulting type has the correct + size. */ + +static struct type * +dwarf_get_base_type (struct dwarf_expr_context *ctx, cu_offset die, int size) +{ + struct type *result; + + if (ctx->funcs->get_base_type) + { + result = ctx->funcs->get_base_type (ctx, die); + if (result == NULL) + error (_("Could not find type for DW_OP_GNU_const_type")); + if (size != 0 && TYPE_LENGTH (result) != size) + error (_("DW_OP_GNU_const_type has different sizes for type and data")); + } + else + /* Anything will do. */ + result = builtin_type (ctx->gdbarch)->builtin_int; + + return result; +} + +/* If = DW_OP_reg0 && *buf <= DW_OP_reg31) + { + if (buf_end - buf != 1) + return -1; + return *buf - DW_OP_reg0; + } + + if (*buf == DW_OP_GNU_regval_type) + { + buf++; + buf = gdb_read_uleb128 (buf, buf_end, &dwarf_reg); + if (buf == NULL) + return -1; + buf = gdb_skip_leb128 (buf, buf_end); + if (buf == NULL) + return -1; + } + else if (*buf == DW_OP_regx) + { + buf++; + buf = gdb_read_uleb128 (buf, buf_end, &dwarf_reg); + if (buf == NULL) + return -1; + } + else + return -1; + if (buf != buf_end || (int) dwarf_reg != dwarf_reg) + return -1; + return dwarf_reg; +} + +/* If = DW_OP_breg0 && *buf <= DW_OP_breg31) + { + dwarf_reg = *buf - DW_OP_breg0; + buf++; + if (buf >= buf_end) + return -1; + } + else if (*buf == DW_OP_bregx) + { + buf++; + buf = gdb_read_uleb128 (buf, buf_end, &dwarf_reg); + if (buf == NULL) + return -1; + if ((int) dwarf_reg != dwarf_reg) + return -1; + } + else + return -1; + + buf = gdb_read_sleb128 (buf, buf_end, &offset); + if (buf == NULL) + return -1; + if (offset != 0) + return -1; + + if (*buf == DW_OP_deref) + { + buf++; + *deref_size_return = -1; + } + else if (*buf == DW_OP_deref_size) + { + buf++; + if (buf >= buf_end) + return -1; + *deref_size_return = *buf++; + } + else + return -1; + + if (buf != buf_end) + return -1; + + return dwarf_reg; +} + +/* If = DW_OP_breg0 && *buf <= DW_OP_breg31) + { + dwarf_reg = *buf - DW_OP_breg0; + buf++; + } + else + { + if (*buf != DW_OP_bregx) + return 0; + buf++; + buf = gdb_read_uleb128 (buf, buf_end, &dwarf_reg); + if (buf == NULL) + return 0; + } + + if (dwarf_reg_to_regnum (gdbarch, dwarf_reg) + != gdbarch_sp_regnum (gdbarch)) + return 0; + + buf = gdb_read_sleb128 (buf, buf_end, &sp_offset); + if (buf == NULL) + return 0; + *sp_offset_return = sp_offset; + if (buf != buf_end || sp_offset != (LONGEST) *sp_offset_return) + return 0; + + return 1; +} + /* The engine for the expression evaluator. Using the context in CTX, evaluate the expression between OP_PTR and OP_END. */ @@ -342,10 +633,15 @@ static void execute_stack_op (struct dwarf_expr_context *ctx, const gdb_byte *op_ptr, const gdb_byte *op_end) { -#define sign_ext(x) ((LONGEST) (((x) ^ sign_bit) - sign_bit)) - ULONGEST sign_bit = (ctx->addr_size >= sizeof (ULONGEST) ? 0 - : ((ULONGEST) 1) << (ctx->addr_size * 8 - 1)); enum bfd_endian byte_order = gdbarch_byte_order (ctx->gdbarch); + /* Old-style "untyped" DWARF values need special treatment in a + couple of places, specifically DW_OP_mod and DW_OP_shr. We need + a special type for these values so we can distinguish them from + values that have an explicit type, because explicitly-typed + values do not need special treatment. This special type must be + different (in the `==' sense) from any base type coming from the + CU. */ + struct type *address_type = dwarf_expr_address_type (ctx); ctx->location = DWARF_VALUE_MEMORY; ctx->initialized = 1; /* Default is initialized. */ @@ -357,7 +653,7 @@ execute_stack_op (struct dwarf_expr_context *ctx, while (op_ptr < op_end) { - enum dwarf_location_atom op = *op_ptr++; + enum dwarf_location_atom op = (enum dwarf_location_atom) *op_ptr++; ULONGEST result; /* Assume the value is not in stack memory. Code that knows otherwise sets this to 1. @@ -366,8 +662,13 @@ execute_stack_op (struct dwarf_expr_context *ctx, This is just an optimization, so it's always ok to punt and leave this as 0. */ int in_stack_memory = 0; - ULONGEST uoffset, reg; - LONGEST offset; + uint64_t uoffset, reg; + int64_t offset; + struct value *result_val = NULL; + + /* The DWARF expression might have a bug causing an infinite + loop. In that case, quitting is the only way out. */ + QUIT; switch (op) { @@ -404,6 +705,7 @@ execute_stack_op (struct dwarf_expr_context *ctx, case DW_OP_lit30: case DW_OP_lit31: result = op - DW_OP_lit0; + result_val = value_from_ulongest (address_type, result); break; case DW_OP_addr: @@ -416,47 +718,70 @@ execute_stack_op (struct dwarf_expr_context *ctx, branching between the address and the TLS op. */ if (op_ptr >= op_end || *op_ptr != DW_OP_GNU_push_tls_address) result += ctx->offset; + result_val = value_from_ulongest (address_type, result); + break; + + case DW_OP_GNU_addr_index: + op_ptr = safe_read_uleb128 (op_ptr, op_end, &uoffset); + result = (ctx->funcs->get_addr_index) (ctx->baton, uoffset); + result += ctx->offset; + result_val = value_from_ulongest (address_type, result); + break; + case DW_OP_GNU_const_index: + op_ptr = safe_read_uleb128 (op_ptr, op_end, &uoffset); + result = (ctx->funcs->get_addr_index) (ctx->baton, uoffset); + result_val = value_from_ulongest (address_type, result); break; case DW_OP_const1u: result = extract_unsigned_integer (op_ptr, 1, byte_order); + result_val = value_from_ulongest (address_type, result); op_ptr += 1; break; case DW_OP_const1s: result = extract_signed_integer (op_ptr, 1, byte_order); + result_val = value_from_ulongest (address_type, result); op_ptr += 1; break; case DW_OP_const2u: result = extract_unsigned_integer (op_ptr, 2, byte_order); + result_val = value_from_ulongest (address_type, result); op_ptr += 2; break; case DW_OP_const2s: result = extract_signed_integer (op_ptr, 2, byte_order); + result_val = value_from_ulongest (address_type, result); op_ptr += 2; break; case DW_OP_const4u: result = extract_unsigned_integer (op_ptr, 4, byte_order); + result_val = value_from_ulongest (address_type, result); op_ptr += 4; break; case DW_OP_const4s: result = extract_signed_integer (op_ptr, 4, byte_order); + result_val = value_from_ulongest (address_type, result); op_ptr += 4; break; case DW_OP_const8u: result = extract_unsigned_integer (op_ptr, 8, byte_order); + result_val = value_from_ulongest (address_type, result); op_ptr += 8; break; case DW_OP_const8s: result = extract_signed_integer (op_ptr, 8, byte_order); + result_val = value_from_ulongest (address_type, result); op_ptr += 8; break; case DW_OP_constu: - op_ptr = read_uleb128 (op_ptr, op_end, &uoffset); + op_ptr = safe_read_uleb128 (op_ptr, op_end, &uoffset); result = uoffset; + result_val = value_from_ulongest (address_type, result); break; case DW_OP_consts: - op_ptr = read_sleb128 (op_ptr, op_end, &offset); + op_ptr = safe_read_sleb128 (op_ptr, op_end, &offset); result = offset; + result_val = value_from_ulongest (address_type, result); break; /* The DW_OP_reg operations are required to occur alone in @@ -498,26 +823,28 @@ execute_stack_op (struct dwarf_expr_context *ctx, && *op_ptr != DW_OP_bit_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 " + "used either alone or in conjunction with DW_OP_piece " "or DW_OP_bit_piece.")); result = op - DW_OP_reg0; + result_val = value_from_ulongest (address_type, result); ctx->location = DWARF_VALUE_REGISTER; break; case DW_OP_regx: - op_ptr = read_uleb128 (op_ptr, op_end, ®); + op_ptr = safe_read_uleb128 (op_ptr, op_end, ®); dwarf_expr_require_composition (op_ptr, op_end, "DW_OP_regx"); result = reg; + result_val = value_from_ulongest (address_type, result); ctx->location = DWARF_VALUE_REGISTER; break; case DW_OP_implicit_value: { - ULONGEST len; + uint64_t len; - op_ptr = read_uleb128 (op_ptr, op_end, &len); + op_ptr = safe_read_uleb128 (op_ptr, op_end, &len); if (op_ptr + len > op_end) error (_("DW_OP_implicit_value: too few bytes available.")); ctx->len = len; @@ -536,17 +863,21 @@ execute_stack_op (struct dwarf_expr_context *ctx, case DW_OP_GNU_implicit_pointer: { - ULONGEST die; - LONGEST len; + int64_t len; - /* The referred-to DIE. */ - ctx->len = extract_unsigned_integer (op_ptr, ctx->addr_size, + if (ctx->ref_addr_size == -1) + error (_("DWARF-2 expression error: DW_OP_GNU_implicit_pointer " + "is not allowed in frame context")); + + /* The referred-to DIE of sect_offset kind. */ + ctx->len = extract_unsigned_integer (op_ptr, ctx->ref_addr_size, byte_order); - op_ptr += ctx->addr_size; + op_ptr += ctx->ref_addr_size; /* The byte offset into the data. */ - op_ptr = read_sleb128 (op_ptr, op_end, &len); + op_ptr = safe_read_sleb128 (op_ptr, op_end, &len); result = (ULONGEST) len; + result_val = value_from_ulongest (address_type, result); ctx->location = DWARF_VALUE_IMPLICIT_POINTER; dwarf_expr_require_composition (op_ptr, op_end, @@ -587,17 +918,20 @@ execute_stack_op (struct dwarf_expr_context *ctx, case DW_OP_breg30: case DW_OP_breg31: { - op_ptr = read_sleb128 (op_ptr, op_end, &offset); - result = (ctx->read_reg) (ctx->baton, op - DW_OP_breg0); + op_ptr = safe_read_sleb128 (op_ptr, op_end, &offset); + result = (ctx->funcs->read_addr_from_reg) (ctx->baton, + op - DW_OP_breg0); result += offset; + result_val = value_from_ulongest (address_type, result); } break; case DW_OP_bregx: { - op_ptr = read_uleb128 (op_ptr, op_end, ®); - op_ptr = read_sleb128 (op_ptr, op_end, &offset); - result = (ctx->read_reg) (ctx->baton, reg); + op_ptr = safe_read_uleb128 (op_ptr, op_end, ®); + op_ptr = safe_read_sleb128 (op_ptr, op_end, &offset); + result = (ctx->funcs->read_addr_from_reg) (ctx->baton, reg); result += offset; + result_val = value_from_ulongest (address_type, result); } break; case DW_OP_fbreg: @@ -606,7 +940,7 @@ execute_stack_op (struct dwarf_expr_context *ctx, size_t datalen; unsigned int before_stack_len; - op_ptr = read_sleb128 (op_ptr, op_end, &offset); + op_ptr = safe_read_sleb128 (op_ptr, op_end, &offset); /* Rather than create a whole new context, we simply record the stack length before execution, then reset it afterwards, effectively erasing whatever the recursive @@ -615,16 +949,19 @@ execute_stack_op (struct dwarf_expr_context *ctx, /* FIXME: cagney/2003-03-26: This code should be using get_frame_base_address(), and then implement a dwarf2 specific this_base method. */ - (ctx->get_frame_base) (ctx->baton, &datastart, &datalen); + (ctx->funcs->get_frame_base) (ctx->baton, &datastart, &datalen); dwarf_expr_eval (ctx, datastart, datalen); if (ctx->location == DWARF_VALUE_MEMORY) result = dwarf_expr_fetch_address (ctx, 0); else if (ctx->location == DWARF_VALUE_REGISTER) - result = (ctx->read_reg) (ctx->baton, dwarf_expr_fetch (ctx, 0)); + result = (ctx->funcs->read_addr_from_reg) + (ctx->baton, + value_as_long (dwarf_expr_fetch (ctx, 0))); else error (_("Not implemented: computing frame " "base using explicit value operator")); result = result + offset; + result_val = value_from_ulongest (address_type, result); in_stack_memory = 1; ctx->stack_len = before_stack_len; ctx->location = DWARF_VALUE_MEMORY; @@ -632,7 +969,7 @@ execute_stack_op (struct dwarf_expr_context *ctx, break; case DW_OP_dup: - result = dwarf_expr_fetch (ctx, 0); + result_val = dwarf_expr_fetch (ctx, 0); in_stack_memory = dwarf_expr_fetch_in_stack_memory (ctx, 0); break; @@ -642,7 +979,7 @@ execute_stack_op (struct dwarf_expr_context *ctx, case DW_OP_pick: offset = *op_ptr++; - result = dwarf_expr_fetch (ctx, offset); + result_val = dwarf_expr_fetch (ctx, offset); in_stack_memory = dwarf_expr_fetch_in_stack_memory (ctx, offset); break; @@ -662,7 +999,7 @@ execute_stack_op (struct dwarf_expr_context *ctx, } case DW_OP_over: - result = dwarf_expr_fetch (ctx, 1); + result_val = dwarf_expr_fetch (ctx, 1); in_stack_memory = dwarf_expr_fetch_in_stack_memory (ctx, 1); break; @@ -685,14 +1022,41 @@ execute_stack_op (struct dwarf_expr_context *ctx, case DW_OP_deref: case DW_OP_deref_size: + case DW_OP_GNU_deref_type: { int addr_size = (op == DW_OP_deref ? ctx->addr_size : *op_ptr++); - gdb_byte *buf = alloca (addr_size); + gdb_byte *buf = (gdb_byte *) alloca (addr_size); CORE_ADDR addr = dwarf_expr_fetch_address (ctx, 0); + struct type *type; + dwarf_expr_pop (ctx); - (ctx->read_mem) (ctx->baton, buf, addr, addr_size); - result = extract_unsigned_integer (buf, addr_size, byte_order); + if (op == DW_OP_GNU_deref_type) + { + cu_offset type_die; + + op_ptr = safe_read_uleb128 (op_ptr, op_end, &uoffset); + type_die.cu_off = uoffset; + type = dwarf_get_base_type (ctx, type_die, 0); + } + else + type = address_type; + + (ctx->funcs->read_mem) (ctx->baton, buf, addr, addr_size); + + /* If the size of the object read from memory is different + from the type length, we need to zero-extend it. */ + if (TYPE_LENGTH (type) != addr_size) + { + ULONGEST result = + extract_unsigned_integer (buf, addr_size, byte_order); + + buf = (gdb_byte *) alloca (TYPE_LENGTH (type)); + store_unsigned_integer (buf, TYPE_LENGTH (type), + byte_order, result); + } + + result_val = value_from_contents_and_address (type, buf, addr); break; } @@ -700,27 +1064,34 @@ execute_stack_op (struct dwarf_expr_context *ctx, case DW_OP_neg: case DW_OP_not: case DW_OP_plus_uconst: - /* Unary operations. */ - result = dwarf_expr_fetch (ctx, 0); - dwarf_expr_pop (ctx); + { + /* Unary operations. */ + result_val = dwarf_expr_fetch (ctx, 0); + dwarf_expr_pop (ctx); - switch (op) - { - case DW_OP_abs: - if (sign_ext (result) < 0) - result = -result; - break; - case DW_OP_neg: - result = -result; - break; - case DW_OP_not: - result = ~result; - break; - case DW_OP_plus_uconst: - op_ptr = read_uleb128 (op_ptr, op_end, ®); - result += reg; - break; - } + switch (op) + { + case DW_OP_abs: + if (value_less (result_val, + value_zero (value_type (result_val), not_lval))) + result_val = value_neg (result_val); + break; + case DW_OP_neg: + result_val = value_neg (result_val); + break; + case DW_OP_not: + dwarf_require_integral (value_type (result_val)); + result_val = value_complement (result_val); + break; + case DW_OP_plus_uconst: + dwarf_require_integral (value_type (result_val)); + result = value_as_long (result_val); + op_ptr = safe_read_uleb128 (op_ptr, op_end, ®); + result += reg; + result_val = value_from_ulongest (address_type, result); + break; + } + } break; case DW_OP_and: @@ -742,7 +1113,7 @@ execute_stack_op (struct dwarf_expr_context *ctx, case DW_OP_ne: { /* Binary operations. */ - ULONGEST first, second; + struct value *first, *second; second = dwarf_expr_fetch (ctx, 0); dwarf_expr_pop (ctx); @@ -750,62 +1121,127 @@ execute_stack_op (struct dwarf_expr_context *ctx, first = dwarf_expr_fetch (ctx, 0); dwarf_expr_pop (ctx); + if (! base_types_equal_p (value_type (first), value_type (second))) + error (_("Incompatible types on DWARF stack")); + switch (op) { case DW_OP_and: - result = first & second; + dwarf_require_integral (value_type (first)); + dwarf_require_integral (value_type (second)); + result_val = value_binop (first, second, BINOP_BITWISE_AND); break; case DW_OP_div: - if (!second) - error (_("Division by zero")); - result = sign_ext (first) / sign_ext (second); + result_val = value_binop (first, second, BINOP_DIV); break; case DW_OP_minus: - result = first - second; + result_val = value_binop (first, second, BINOP_SUB); break; case DW_OP_mod: - if (!second) - error (_("Division by zero")); - result = first % second; + { + int cast_back = 0; + struct type *orig_type = value_type (first); + + /* We have to special-case "old-style" untyped values + -- these must have mod computed using unsigned + math. */ + if (orig_type == address_type) + { + struct type *utype + = get_unsigned_type (ctx->gdbarch, orig_type); + + cast_back = 1; + first = value_cast (utype, first); + second = value_cast (utype, second); + } + /* Note that value_binop doesn't handle float or + decimal float here. This seems unimportant. */ + result_val = value_binop (first, second, BINOP_MOD); + if (cast_back) + result_val = value_cast (orig_type, result_val); + } break; case DW_OP_mul: - result = first * second; + result_val = value_binop (first, second, BINOP_MUL); break; case DW_OP_or: - result = first | second; + dwarf_require_integral (value_type (first)); + dwarf_require_integral (value_type (second)); + result_val = value_binop (first, second, BINOP_BITWISE_IOR); break; case DW_OP_plus: - result = first + second; + result_val = value_binop (first, second, BINOP_ADD); break; case DW_OP_shl: - result = first << second; + dwarf_require_integral (value_type (first)); + dwarf_require_integral (value_type (second)); + result_val = value_binop (first, second, BINOP_LSH); break; case DW_OP_shr: - result = first >> second; + dwarf_require_integral (value_type (first)); + dwarf_require_integral (value_type (second)); + if (!TYPE_UNSIGNED (value_type (first))) + { + struct type *utype + = get_unsigned_type (ctx->gdbarch, value_type (first)); + + first = value_cast (utype, first); + } + + result_val = value_binop (first, second, BINOP_RSH); + /* Make sure we wind up with the same type we started + with. */ + if (value_type (result_val) != value_type (second)) + result_val = value_cast (value_type (second), result_val); break; case DW_OP_shra: - result = sign_ext (first) >> second; + dwarf_require_integral (value_type (first)); + dwarf_require_integral (value_type (second)); + if (TYPE_UNSIGNED (value_type (first))) + { + struct type *stype + = get_signed_type (ctx->gdbarch, value_type (first)); + + first = value_cast (stype, first); + } + + result_val = value_binop (first, second, BINOP_RSH); + /* Make sure we wind up with the same type we started + with. */ + if (value_type (result_val) != value_type (second)) + result_val = value_cast (value_type (second), result_val); break; case DW_OP_xor: - result = first ^ second; + dwarf_require_integral (value_type (first)); + dwarf_require_integral (value_type (second)); + result_val = value_binop (first, second, BINOP_BITWISE_XOR); break; case DW_OP_le: - result = sign_ext (first) <= sign_ext (second); + /* A <= B is !(B < A). */ + result = ! value_less (second, first); + result_val = value_from_ulongest (address_type, result); break; case DW_OP_ge: - result = sign_ext (first) >= sign_ext (second); + /* A >= B is !(A < B). */ + result = ! value_less (first, second); + result_val = value_from_ulongest (address_type, result); break; case DW_OP_eq: - result = sign_ext (first) == sign_ext (second); + result = value_equal (first, second); + result_val = value_from_ulongest (address_type, result); break; case DW_OP_lt: - result = sign_ext (first) < sign_ext (second); + result = value_less (first, second); + result_val = value_from_ulongest (address_type, result); break; case DW_OP_gt: - result = sign_ext (first) > sign_ext (second); + /* A > B is B < A. */ + result = value_less (second, first); + result_val = value_from_ulongest (address_type, result); break; case DW_OP_ne: - result = sign_ext (first) != sign_ext (second); + result = ! value_equal (first, second); + result_val = value_from_ulongest (address_type, result); break; default: internal_error (__FILE__, __LINE__, @@ -815,7 +1251,8 @@ execute_stack_op (struct dwarf_expr_context *ctx, break; case DW_OP_call_frame_cfa: - result = (ctx->get_frame_cfa) (ctx->baton); + result = (ctx->funcs->get_frame_cfa) (ctx->baton); + result_val = value_from_ulongest (address_type, result); in_stack_memory = 1; break; @@ -828,9 +1265,10 @@ execute_stack_op (struct dwarf_expr_context *ctx, control block at which the variable is located. Nothing should follow this operator, so the top of stack would be returned. */ - result = dwarf_expr_fetch (ctx, 0); + result = value_as_long (dwarf_expr_fetch (ctx, 0)); dwarf_expr_pop (ctx); - result = (ctx->get_tls_address) (ctx->baton, result); + result = (ctx->funcs->get_tls_address) (ctx->baton, result); + result_val = value_from_ulongest (address_type, result); break; case DW_OP_skip: @@ -840,11 +1278,17 @@ execute_stack_op (struct dwarf_expr_context *ctx, goto no_push; case DW_OP_bra: - offset = extract_signed_integer (op_ptr, 2, byte_order); - op_ptr += 2; - if (dwarf_expr_fetch (ctx, 0) != 0) - op_ptr += offset; - dwarf_expr_pop (ctx); + { + struct value *val; + + offset = extract_signed_integer (op_ptr, 2, byte_order); + op_ptr += 2; + val = dwarf_expr_fetch (ctx, 0); + dwarf_require_integral (value_type (val)); + if (value_as_long (val) != 0) + op_ptr += offset; + dwarf_expr_pop (ctx); + } goto no_push; case DW_OP_nop: @@ -852,10 +1296,10 @@ execute_stack_op (struct dwarf_expr_context *ctx, case DW_OP_piece: { - ULONGEST size; + uint64_t size; /* Record the piece. */ - op_ptr = read_uleb128 (op_ptr, op_end, &size); + op_ptr = safe_read_uleb128 (op_ptr, op_end, &size); add_piece (ctx, 8 * size, 0); /* Pop off the address/regnum, and reset the location @@ -869,11 +1313,11 @@ execute_stack_op (struct dwarf_expr_context *ctx, case DW_OP_bit_piece: { - ULONGEST size, offset; + uint64_t size, offset; /* Record the piece. */ - op_ptr = read_uleb128 (op_ptr, op_end, &size); - op_ptr = read_uleb128 (op_ptr, op_end, &offset); + op_ptr = safe_read_uleb128 (op_ptr, op_end, &size); + op_ptr = safe_read_uleb128 (op_ptr, op_end, &offset); add_piece (ctx, size, offset); /* Pop off the address/regnum, and reset the location @@ -894,24 +1338,159 @@ execute_stack_op (struct dwarf_expr_context *ctx, goto no_push; case DW_OP_call2: - result = extract_unsigned_integer (op_ptr, 2, byte_order); - op_ptr += 2; - ctx->dwarf_call (ctx, result); + { + cu_offset offset; + + offset.cu_off = extract_unsigned_integer (op_ptr, 2, byte_order); + op_ptr += 2; + ctx->funcs->dwarf_call (ctx, offset); + } goto no_push; case DW_OP_call4: - result = extract_unsigned_integer (op_ptr, 4, byte_order); - op_ptr += 4; - ctx->dwarf_call (ctx, result); + { + cu_offset offset; + + offset.cu_off = extract_unsigned_integer (op_ptr, 4, byte_order); + op_ptr += 4; + ctx->funcs->dwarf_call (ctx, offset); + } goto no_push; + + case DW_OP_GNU_entry_value: + { + uint64_t len; + CORE_ADDR deref_size; + union call_site_parameter_u kind_u; + + op_ptr = safe_read_uleb128 (op_ptr, op_end, &len); + if (op_ptr + len > op_end) + error (_("DW_OP_GNU_entry_value: too few bytes available.")); + + kind_u.dwarf_reg = dwarf_block_to_dwarf_reg (op_ptr, op_ptr + len); + if (kind_u.dwarf_reg != -1) + { + op_ptr += len; + ctx->funcs->push_dwarf_reg_entry_value (ctx, + CALL_SITE_PARAMETER_DWARF_REG, + kind_u, + -1 /* deref_size */); + goto no_push; + } + + kind_u.dwarf_reg = dwarf_block_to_dwarf_reg_deref (op_ptr, + op_ptr + len, + &deref_size); + if (kind_u.dwarf_reg != -1) + { + if (deref_size == -1) + deref_size = ctx->addr_size; + op_ptr += len; + ctx->funcs->push_dwarf_reg_entry_value (ctx, + CALL_SITE_PARAMETER_DWARF_REG, + kind_u, deref_size); + goto no_push; + } + + error (_("DWARF-2 expression error: DW_OP_GNU_entry_value is " + "supported only for single DW_OP_reg* " + "or for DW_OP_breg*(0)+DW_OP_deref*")); + } + + case DW_OP_GNU_parameter_ref: + { + union call_site_parameter_u kind_u; + + kind_u.param_offset.cu_off = extract_unsigned_integer (op_ptr, 4, + byte_order); + op_ptr += 4; + ctx->funcs->push_dwarf_reg_entry_value (ctx, + CALL_SITE_PARAMETER_PARAM_OFFSET, + kind_u, + -1 /* deref_size */); + } + goto no_push; + + case DW_OP_GNU_const_type: + { + cu_offset type_die; + int n; + const gdb_byte *data; + struct type *type; + + op_ptr = safe_read_uleb128 (op_ptr, op_end, &uoffset); + type_die.cu_off = uoffset; + n = *op_ptr++; + data = op_ptr; + op_ptr += n; + + type = dwarf_get_base_type (ctx, type_die, n); + result_val = value_from_contents (type, data); + } + break; + + case DW_OP_GNU_regval_type: + { + cu_offset type_die; + struct type *type; + + op_ptr = safe_read_uleb128 (op_ptr, op_end, ®); + op_ptr = safe_read_uleb128 (op_ptr, op_end, &uoffset); + type_die.cu_off = uoffset; + + type = dwarf_get_base_type (ctx, type_die, 0); + result_val = ctx->funcs->get_reg_value (ctx->baton, type, reg); + } + break; + + case DW_OP_GNU_convert: + case DW_OP_GNU_reinterpret: + { + cu_offset type_die; + struct type *type; + + op_ptr = safe_read_uleb128 (op_ptr, op_end, &uoffset); + type_die.cu_off = uoffset; + + if (type_die.cu_off == 0) + type = address_type; + else + type = dwarf_get_base_type (ctx, type_die, 0); + + result_val = dwarf_expr_fetch (ctx, 0); + dwarf_expr_pop (ctx); + + if (op == DW_OP_GNU_convert) + result_val = value_cast (type, result_val); + else if (type == value_type (result_val)) + { + /* Nothing. */ + } + else if (TYPE_LENGTH (type) + != TYPE_LENGTH (value_type (result_val))) + error (_("DW_OP_GNU_reinterpret has wrong size")); + else + result_val + = value_from_contents (type, + value_contents_all (result_val)); + } + break; + + case DW_OP_push_object_address: + /* Return the address of the object we are currently observing. */ + result = (ctx->funcs->get_object_address) (ctx->baton); + result_val = value_from_ulongest (address_type, result); + break; default: error (_("Unhandled dwarf expression opcode 0x%x"), op); } /* Most things push a result value. */ - dwarf_expr_push (ctx, result, in_stack_memory); + gdb_assert (result_val != NULL); + dwarf_expr_push (ctx, result_val, in_stack_memory); no_push: + ; } /* To simplify our main caller, if the result is an implicit @@ -920,7 +1499,86 @@ execute_stack_op (struct dwarf_expr_context *ctx, if (ctx->location == DWARF_VALUE_IMPLICIT_POINTER) add_piece (ctx, 8 * ctx->addr_size, 0); +abort_expression: ctx->recursion_depth--; gdb_assert (ctx->recursion_depth >= 0); -#undef sign_ext +} + +/* Stub dwarf_expr_context_funcs.get_frame_base implementation. */ + +void +ctx_no_get_frame_base (void *baton, const gdb_byte **start, size_t *length) +{ + error (_("%s is invalid in this context"), "DW_OP_fbreg"); +} + +/* Stub dwarf_expr_context_funcs.get_frame_cfa implementation. */ + +CORE_ADDR +ctx_no_get_frame_cfa (void *baton) +{ + error (_("%s is invalid in this context"), "DW_OP_call_frame_cfa"); +} + +/* Stub dwarf_expr_context_funcs.get_frame_pc implementation. */ + +CORE_ADDR +ctx_no_get_frame_pc (void *baton) +{ + error (_("%s is invalid in this context"), "DW_OP_GNU_implicit_pointer"); +} + +/* Stub dwarf_expr_context_funcs.get_tls_address implementation. */ + +CORE_ADDR +ctx_no_get_tls_address (void *baton, CORE_ADDR offset) +{ + error (_("%s is invalid in this context"), "DW_OP_GNU_push_tls_address"); +} + +/* Stub dwarf_expr_context_funcs.dwarf_call implementation. */ + +void +ctx_no_dwarf_call (struct dwarf_expr_context *ctx, cu_offset die_offset) +{ + error (_("%s is invalid in this context"), "DW_OP_call*"); +} + +/* Stub dwarf_expr_context_funcs.get_base_type implementation. */ + +struct type * +ctx_no_get_base_type (struct dwarf_expr_context *ctx, cu_offset die) +{ + error (_("Support for typed DWARF is not supported in this context")); +} + +/* Stub dwarf_expr_context_funcs.push_dwarf_block_entry_value + implementation. */ + +void +ctx_no_push_dwarf_reg_entry_value (struct dwarf_expr_context *ctx, + enum call_site_parameter_kind kind, + union call_site_parameter_u kind_u, + int deref_size) +{ + internal_error (__FILE__, __LINE__, + _("Support for DW_OP_GNU_entry_value is unimplemented")); +} + +/* Stub dwarf_expr_context_funcs.get_addr_index implementation. */ + +CORE_ADDR +ctx_no_get_addr_index (void *baton, unsigned int index) +{ + error (_("%s is invalid in this context"), "DW_OP_GNU_addr_index"); +} + +/* Provide a prototype to silence -Wmissing-prototypes. */ +extern initialize_file_ftype _initialize_dwarf2expr; + +void +_initialize_dwarf2expr (void) +{ + dwarf_arch_cookie + = gdbarch_data_register_post_init (dwarf_gdbarch_types_init); }