X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=gdb%2Fdwarf2expr.c;h=2e500e94baa0bb61da326c6cada5eb1ce33fcf61;hb=d7f3ff3ea7830389f458be7c5eadb5d4a4e0a90b;hp=e93f6486c4daf063b82d1f79c7afff56c3c9ddfc;hpb=3019eac3a2ebb5509f71db9fb21f131a7e759a5d;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/dwarf2expr.c b/gdb/dwarf2expr.c index e93f6486c4..2e500e94ba 100644 --- a/gdb/dwarf2expr.c +++ b/gdb/dwarf2expr.c @@ -1,7 +1,6 @@ /* DWARF 2 Expression Evaluator. - Copyright (C) 2001-2003, 2005, 2007-2012 Free Software Foundation, - Inc. + Copyright (C) 2001-2015 Free Software Foundation, Inc. Contributed by Daniel Berlin (dan@dberlin.org) @@ -27,7 +26,7 @@ #include "gdbcore.h" #include "dwarf2.h" #include "dwarf2expr.h" -#include "gdb_assert.h" +#include "dwarf2loc.h" /* Local prototypes. */ @@ -66,8 +65,9 @@ dwarf_gdbarch_types_init (struct gdbarch *gdbarch) static struct type * dwarf_expr_address_type (struct dwarf_expr_context *ctx) { - struct dwarf_gdbarch_types *types = gdbarch_data (ctx->gdbarch, - dwarf_arch_cookie); + struct dwarf_gdbarch_types *types + = (struct dwarf_gdbarch_types *) gdbarch_data (ctx->gdbarch, + dwarf_arch_cookie); int ndx; if (ctx->addr_size == 2) @@ -96,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; @@ -122,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. */ @@ -143,8 +142,7 @@ 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; } } @@ -273,7 +271,7 @@ 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)) { - gdb_byte *buf = alloca (ctx->addr_size); + gdb_byte *buf = (gdb_byte *) alloca (ctx->addr_size); struct type *int_type = get_unsigned_type (ctx->gdbarch, value_type (result_val)); @@ -312,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; @@ -342,7 +339,7 @@ add_piece (struct dwarf_expr_context *ctx, ULONGEST size, ULONGEST offset) } else if (p->location == DWARF_VALUE_IMPLICIT_POINTER) { - p->v.ptr.die.cu_off = ctx->len; + 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) @@ -369,60 +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. R can be NULL, the constant is then only skipped. */ +/* 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 |= ((ULONGEST) (byte & 0x7f)) << shift; - if ((byte & 0x80) == 0) - break; - shift += 7; - } - if (r) - *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. R can be NULL, the constant is then only skipped. */ +/* 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 |= ((ULONGEST) (byte & 0x7f)) << shift; - shift += 7; - if ((byte & 0x80) == 0) - break; - } - if (shift < (sizeof (*r) * 8) && (byte & 0x40) != 0) - result |= -(((LONGEST) 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; +} - if (r) - *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; } @@ -489,7 +462,7 @@ dwarf_get_base_type (struct dwarf_expr_context *ctx, cu_offset die, int size) int dwarf_block_to_dwarf_reg (const gdb_byte *buf, const gdb_byte *buf_end) { - ULONGEST dwarf_reg; + uint64_t dwarf_reg; if (buf_end <= buf) return -1; @@ -503,13 +476,19 @@ dwarf_block_to_dwarf_reg (const gdb_byte *buf, const gdb_byte *buf_end) if (*buf == DW_OP_GNU_regval_type) { buf++; - buf = read_uleb128 (buf, buf_end, &dwarf_reg); - buf = read_uleb128 (buf, buf_end, NULL); + 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 = read_uleb128 (buf, buf_end, &dwarf_reg); + buf = gdb_read_uleb128 (buf, buf_end, &dwarf_reg); + if (buf == NULL) + return -1; } else return -1; @@ -527,31 +506,35 @@ int dwarf_block_to_dwarf_reg_deref (const gdb_byte *buf, const gdb_byte *buf_end, CORE_ADDR *deref_size_return) { - ULONGEST dwarf_reg; - LONGEST offset; + uint64_t dwarf_reg; + int64_t offset; if (buf_end <= buf) return -1; + if (*buf >= 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 = read_uleb128 (buf, buf_end, &dwarf_reg); + 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 = read_sleb128 (buf, buf_end, &offset); - if (offset != 0) + buf = gdb_read_sleb128 (buf, buf_end, &offset); + if (buf == NULL) return -1; - - if (buf >= buf_end) + if (offset != 0) return -1; if (*buf == DW_OP_deref) @@ -582,7 +565,7 @@ int dwarf_block_to_fb_offset (const gdb_byte *buf, const gdb_byte *buf_end, CORE_ADDR *fb_offset_return) { - LONGEST fb_offset; + int64_t fb_offset; if (buf_end <= buf) return 0; @@ -591,7 +574,9 @@ dwarf_block_to_fb_offset (const gdb_byte *buf, const gdb_byte *buf_end, return 0; buf++; - buf = read_sleb128 (buf, buf_end, &fb_offset); + buf = gdb_read_sleb128 (buf, buf_end, &fb_offset); + if (buf == NULL) + return 0; *fb_offset_return = fb_offset; if (buf != buf_end || fb_offset != (LONGEST) *fb_offset_return) return 0; @@ -607,8 +592,8 @@ int dwarf_block_to_sp_offset (struct gdbarch *gdbarch, const gdb_byte *buf, const gdb_byte *buf_end, CORE_ADDR *sp_offset_return) { - ULONGEST dwarf_reg; - LONGEST sp_offset; + uint64_t dwarf_reg; + int64_t sp_offset; if (buf_end <= buf) return 0; @@ -622,14 +607,18 @@ dwarf_block_to_sp_offset (struct gdbarch *gdbarch, const gdb_byte *buf, if (*buf != DW_OP_bregx) return 0; buf++; - buf = read_uleb128 (buf, buf_end, &dwarf_reg); + buf = gdb_read_uleb128 (buf, buf_end, &dwarf_reg); + if (buf == NULL) + return 0; } - if (gdbarch_dwarf2_reg_to_regnum (gdbarch, dwarf_reg) + if (dwarf_reg_to_regnum (gdbarch, dwarf_reg) != gdbarch_sp_regnum (gdbarch)) return 0; - buf = read_sleb128 (buf, buf_end, &sp_offset); + 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; @@ -664,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. @@ -673,8 +662,8 @@ 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 @@ -733,7 +722,13 @@ execute_stack_op (struct dwarf_expr_context *ctx, break; case DW_OP_GNU_addr_index: - op_ptr = read_uleb128 (op_ptr, op_end, &uoffset); + 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; @@ -779,12 +774,12 @@ execute_stack_op (struct dwarf_expr_context *ctx, 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; @@ -837,7 +832,7 @@ execute_stack_op (struct dwarf_expr_context *ctx, 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; @@ -847,9 +842,9 @@ execute_stack_op (struct dwarf_expr_context *ctx, 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; @@ -868,20 +863,19 @@ execute_stack_op (struct dwarf_expr_context *ctx, case DW_OP_GNU_implicit_pointer: { - ULONGEST die; - LONGEST len; + int64_t len; 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 cu_offset kind. */ + /* The referred-to DIE of sect_offset kind. */ ctx->len = extract_unsigned_integer (op_ptr, ctx->ref_addr_size, byte_order); 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); @@ -924,17 +918,18 @@ 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->funcs->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->funcs->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); } @@ -945,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 @@ -959,8 +954,9 @@ execute_stack_op (struct dwarf_expr_context *ctx, if (ctx->location == DWARF_VALUE_MEMORY) result = dwarf_expr_fetch_address (ctx, 0); else if (ctx->location == DWARF_VALUE_REGISTER) - result = (ctx->funcs->read_reg) (ctx->baton, - value_as_long (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")); @@ -1029,7 +1025,7 @@ execute_stack_op (struct dwarf_expr_context *ctx, 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; @@ -1039,7 +1035,7 @@ execute_stack_op (struct dwarf_expr_context *ctx, { cu_offset type_die; - op_ptr = read_uleb128 (op_ptr, op_end, &uoffset); + op_ptr = safe_read_uleb128 (op_ptr, op_end, &uoffset); type_die.cu_off = uoffset; type = dwarf_get_base_type (ctx, type_die, 0); } @@ -1055,7 +1051,7 @@ execute_stack_op (struct dwarf_expr_context *ctx, ULONGEST result = extract_unsigned_integer (buf, addr_size, byte_order); - buf = alloca (TYPE_LENGTH (type)); + buf = (gdb_byte *) alloca (TYPE_LENGTH (type)); store_unsigned_integer (buf, TYPE_LENGTH (type), byte_order, result); } @@ -1090,7 +1086,7 @@ execute_stack_op (struct dwarf_expr_context *ctx, case DW_OP_plus_uconst: dwarf_require_integral (value_type (result_val)); result = value_as_long (result_val); - op_ptr = read_uleb128 (op_ptr, op_end, ®); + op_ptr = safe_read_uleb128 (op_ptr, op_end, ®); result += reg; result_val = value_from_ulongest (address_type, result); break; @@ -1300,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 @@ -1317,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 @@ -1363,34 +1359,36 @@ execute_stack_op (struct dwarf_expr_context *ctx, case DW_OP_GNU_entry_value: { - ULONGEST len; - int dwarf_reg; + uint64_t len; CORE_ADDR deref_size; + union call_site_parameter_u kind_u; - 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_GNU_entry_value: too few bytes available.")); - dwarf_reg = dwarf_block_to_dwarf_reg (op_ptr, op_ptr + len); - if (dwarf_reg != -1) + 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, dwarf_reg, - 0 /* unused */, + ctx->funcs->push_dwarf_reg_entry_value (ctx, + CALL_SITE_PARAMETER_DWARF_REG, + kind_u, -1 /* deref_size */); goto no_push; } - dwarf_reg = dwarf_block_to_dwarf_reg_deref (op_ptr, op_ptr + len, - &deref_size); - if (dwarf_reg != -1) + 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, dwarf_reg, - 0 /* unused */, - deref_size); + ctx->funcs->push_dwarf_reg_entry_value (ctx, + CALL_SITE_PARAMETER_DWARF_REG, + kind_u, deref_size); goto no_push; } @@ -1399,6 +1397,20 @@ execute_stack_op (struct dwarf_expr_context *ctx, "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; @@ -1406,7 +1418,7 @@ execute_stack_op (struct dwarf_expr_context *ctx, const gdb_byte *data; struct type *type; - op_ptr = read_uleb128 (op_ptr, op_end, &uoffset); + op_ptr = safe_read_uleb128 (op_ptr, op_end, &uoffset); type_die.cu_off = uoffset; n = *op_ptr++; data = op_ptr; @@ -1422,15 +1434,12 @@ execute_stack_op (struct dwarf_expr_context *ctx, cu_offset type_die; struct type *type; - op_ptr = read_uleb128 (op_ptr, op_end, ®); - op_ptr = read_uleb128 (op_ptr, op_end, &uoffset); + 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 = (ctx->funcs->read_reg) (ctx->baton, reg); - result_val = value_from_ulongest (address_type, result); - result_val = value_from_contents (type, - value_contents_all (result_val)); + result_val = ctx->funcs->get_reg_value (ctx->baton, type, reg); } break; @@ -1440,7 +1449,7 @@ execute_stack_op (struct dwarf_expr_context *ctx, cu_offset type_die; struct type *type; - op_ptr = read_uleb128 (op_ptr, op_end, &uoffset); + op_ptr = safe_read_uleb128 (op_ptr, op_end, &uoffset); type_die.cu_off = uoffset; if (type_die.cu_off == 0) @@ -1467,6 +1476,12 @@ execute_stack_op (struct dwarf_expr_context *ctx, } 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); } @@ -1542,7 +1557,8 @@ ctx_no_get_base_type (struct dwarf_expr_context *ctx, cu_offset die) void ctx_no_push_dwarf_reg_entry_value (struct dwarf_expr_context *ctx, - int dwarf_reg, CORE_ADDR fb_offset, + enum call_site_parameter_kind kind, + union call_site_parameter_u kind_u, int deref_size) { internal_error (__FILE__, __LINE__,