X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=gdb%2Fdwarf2expr.c;h=f611940ad3193a672430fddde0f5f7d117ad2b1f;hb=26c957f12762816a90d5145c7c527ca48c890855;hp=6ba48314287a4c992529949f331a98909878b873;hpb=61baf725eca99af2569262d10aca03dcde2698f6;p=external%2Fbinutils.git diff --git a/gdb/dwarf2expr.c b/gdb/dwarf2expr.c index 6ba4831..f611940 100644 --- a/gdb/dwarf2expr.c +++ b/gdb/dwarf2expr.c @@ -1,6 +1,6 @@ /* DWARF 2 Expression Evaluator. - Copyright (C) 2001-2017 Free Software Foundation, Inc. + Copyright (C) 2001-2019 Free Software Foundation, Inc. Contributed by Daniel Berlin (dan@dberlin.org) @@ -27,6 +27,8 @@ #include "dwarf2.h" #include "dwarf2expr.h" #include "dwarf2loc.h" +#include "gdbsupport/underlying.h" +#include "gdbarch.h" /* Cookie for gdbarch data. */ @@ -87,10 +89,7 @@ dwarf_expr_context::address_type () const /* Create a new context for the expression evaluator. */ dwarf_expr_context::dwarf_expr_context () -: stack (NULL), - stack_len (0), - stack_allocated (10), - gdbarch (NULL), +: gdbarch (NULL), addr_size (0), ref_addr_size (0), offset (0), @@ -99,53 +98,22 @@ dwarf_expr_context::dwarf_expr_context () location (DWARF_VALUE_MEMORY), len (0), data (NULL), - initialized (0), - num_pieces (0), - pieces (NULL) + initialized (0) { - this->stack = XNEWVEC (struct dwarf_stack_value, this->stack_allocated); -} - -/* Clean up a dwarf_expr_context. */ - -dwarf_expr_context::~dwarf_expr_context () -{ - xfree (this->stack); - xfree (this->pieces); -} - -/* Expand the memory allocated stack to contain at least - NEED more elements than are currently used. */ - -void -dwarf_expr_context::grow_stack (size_t need) -{ - if (this->stack_len + need > this->stack_allocated) - { - size_t newlen = this->stack_len + need + 10; - - this->stack = XRESIZEVEC (struct dwarf_stack_value, this->stack, newlen); - this->stack_allocated = newlen; - } } /* Push VALUE onto the stack. */ void -dwarf_expr_context::push (struct value *value, int in_stack_memory) +dwarf_expr_context::push (struct value *value, bool in_stack_memory) { - struct dwarf_stack_value *v; - - grow_stack (1); - v = &this->stack[this->stack_len++]; - v->value = value; - v->in_stack_memory = in_stack_memory; + stack.emplace_back (value, in_stack_memory); } /* Push VALUE onto the stack. */ void -dwarf_expr_context::push_address (CORE_ADDR value, int in_stack_memory) +dwarf_expr_context::push_address (CORE_ADDR value, bool in_stack_memory) { push (value_from_ulongest (address_type (), value), in_stack_memory); } @@ -155,9 +123,10 @@ dwarf_expr_context::push_address (CORE_ADDR value, int in_stack_memory) void dwarf_expr_context::pop () { - if (this->stack_len <= 0) + if (stack.empty ()) error (_("dwarf expression stack underflow")); - this->stack_len--; + + stack.pop_back (); } /* Retrieve the N'th item on the stack. */ @@ -165,11 +134,11 @@ dwarf_expr_context::pop () struct value * dwarf_expr_context::fetch (int n) { - if (this->stack_len <= n) + if (stack.size () <= n) error (_("Asked for position %d of stack, " - "stack only has %d elements on it."), - n, this->stack_len); - return this->stack[this->stack_len - (1 + n)].value; + "stack only has %zu elements on it."), + n, stack.size ()); + return stack[stack.size () - (1 + n)].value; } /* Require that TYPE be an integral type; throw an exception if not. */ @@ -262,69 +231,64 @@ dwarf_expr_context::fetch_address (int n) /* Retrieve the in_stack_memory flag of the N'th item on the stack. */ -int +bool dwarf_expr_context::fetch_in_stack_memory (int n) { - if (this->stack_len <= n) + if (stack.size () <= n) error (_("Asked for position %d of stack, " - "stack only has %d elements on it."), - n, this->stack_len); - return this->stack[this->stack_len - (1 + n)].in_stack_memory; + "stack only has %zu elements on it."), + n, stack.size ()); + return stack[stack.size () - (1 + n)].in_stack_memory; } /* Return true if the expression stack is empty. */ -int +bool dwarf_expr_context::stack_empty_p () const { - return this->stack_len == 0; + return stack.empty (); } /* Add a new piece to the dwarf_expr_context's piece list. */ void dwarf_expr_context::add_piece (ULONGEST size, ULONGEST offset) { - struct dwarf_expr_piece *p; - - this->num_pieces++; - - this->pieces - = XRESIZEVEC (struct dwarf_expr_piece, this->pieces, this->num_pieces); + this->pieces.emplace_back (); + dwarf_expr_piece &p = this->pieces.back (); - p = &this->pieces[this->num_pieces - 1]; - p->location = this->location; - p->size = size; - p->offset = offset; + p.location = this->location; + p.size = size; + p.offset = offset; - if (p->location == DWARF_VALUE_LITERAL) + if (p.location == DWARF_VALUE_LITERAL) { - p->v.literal.data = this->data; - p->v.literal.length = this->len; + p.v.literal.data = this->data; + p.v.literal.length = this->len; } else if (stack_empty_p ()) { - p->location = DWARF_VALUE_OPTIMIZED_OUT; + p.location = DWARF_VALUE_OPTIMIZED_OUT; /* Also reset the context's location, for our callers. This is a somewhat strange approach, but this lets us avoid setting the location to DWARF_VALUE_MEMORY in all the individual cases in the evaluator. */ this->location = DWARF_VALUE_OPTIMIZED_OUT; } - else if (p->location == DWARF_VALUE_MEMORY) + else if (p.location == DWARF_VALUE_MEMORY) { - p->v.mem.addr = fetch_address (0); - p->v.mem.in_stack_memory = fetch_in_stack_memory (0); + p.v.mem.addr = fetch_address (0); + p.v.mem.in_stack_memory = fetch_in_stack_memory (0); } - else if (p->location == DWARF_VALUE_IMPLICIT_POINTER) + else if (p.location == DWARF_VALUE_IMPLICIT_POINTER) { - p->v.ptr.die.sect_off = this->len; - p->v.ptr.offset = value_as_long (fetch (0)); + p.v.ptr.die_sect_off = (sect_offset) this->len; + p.v.ptr.offset = value_as_long (fetch (0)); } - else if (p->location == DWARF_VALUE_REGISTER) - p->v.regno = value_as_long (fetch (0)); + else if (p.location == DWARF_VALUE_REGISTER) + p.v.regno = value_as_long (fetch (0)); else { - p->v.value = fetch (0); + p.v.value = fetch (0); } } @@ -423,7 +387,7 @@ dwarf_block_to_dwarf_reg (const gdb_byte *buf, const gdb_byte *buf_end) return *buf - DW_OP_reg0; } - if (*buf == DW_OP_GNU_regval_type) + if (*buf == DW_OP_regval_type || *buf == DW_OP_GNU_regval_type) { buf++; buf = gdb_read_uleb128 (buf, buf_end, &dwarf_reg); @@ -606,12 +570,12 @@ dwarf_expr_context::execute_stack_op (const gdb_byte *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. + Code that knows otherwise sets this to true. Some arithmetic on stack addresses can probably be assumed to still be a stack address, but we skip this complication for now. This is just an optimization, so it's always ok to punt - and leave this as 0. */ - int in_stack_memory = 0; + and leave this as false. */ + bool in_stack_memory = false; uint64_t uoffset, reg; int64_t offset; struct value *result_val = NULL; @@ -671,6 +635,7 @@ dwarf_expr_context::execute_stack_op (const gdb_byte *op_ptr, result_val = value_from_ulongest (address_type, result); break; + case DW_OP_addrx: case DW_OP_GNU_addr_index: op_ptr = safe_read_uleb128 (op_ptr, op_end, &uoffset); result = this->get_addr_index (uoffset); @@ -805,12 +770,13 @@ dwarf_expr_context::execute_stack_op (const gdb_byte *op_ptr, dwarf_expr_require_composition (op_ptr, op_end, "DW_OP_stack_value"); goto no_push; + case DW_OP_implicit_pointer: case DW_OP_GNU_implicit_pointer: { int64_t len; if (this->ref_addr_size == -1) - error (_("DWARF-2 expression error: DW_OP_GNU_implicit_pointer " + error (_("DWARF-2 expression error: DW_OP_implicit_pointer " "is not allowed in frame context")); /* The referred-to DIE of sect_offset kind. */ @@ -825,7 +791,7 @@ dwarf_expr_context::execute_stack_op (const gdb_byte *op_ptr, this->location = DWARF_VALUE_IMPLICIT_POINTER; dwarf_expr_require_composition (op_ptr, op_end, - "DW_OP_GNU_implicit_pointer"); + "DW_OP_implicit_pointer"); } break; @@ -881,14 +847,16 @@ dwarf_expr_context::execute_stack_op (const gdb_byte *op_ptr, { const gdb_byte *datastart; size_t datalen; - unsigned int before_stack_len; 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 - call put there. */ - before_stack_len = this->stack_len; + backup the current stack locally and install a new empty stack, + then reset it afterwards, effectively erasing whatever the + recursive call put there. */ + std::vector saved_stack = std::move (stack); + stack.clear (); + /* FIXME: cagney/2003-03-26: This code should be using get_frame_base_address(), and then implement a dwarf2 specific this_base method. */ @@ -903,8 +871,11 @@ dwarf_expr_context::execute_stack_op (const gdb_byte *op_ptr, "base using explicit value operator")); result = result + offset; result_val = value_from_ulongest (address_type, result); - in_stack_memory = 1; - this->stack_len = before_stack_len; + in_stack_memory = true; + + /* Restore the content of the original stack. */ + stack = std::move (saved_stack); + this->location = DWARF_VALUE_MEMORY; } break; @@ -926,16 +897,14 @@ dwarf_expr_context::execute_stack_op (const gdb_byte *op_ptr, case DW_OP_swap: { - struct dwarf_stack_value t1, t2; - - if (this->stack_len < 2) + if (stack.size () < 2) error (_("Not enough elements for " - "DW_OP_swap. Need 2, have %d."), - this->stack_len); - t1 = this->stack[this->stack_len - 1]; - t2 = this->stack[this->stack_len - 2]; - this->stack[this->stack_len - 1] = t2; - this->stack[this->stack_len - 2] = t1; + "DW_OP_swap. Need 2, have %zu."), + stack.size ()); + + dwarf_stack_value &t1 = stack[stack.size () - 1]; + dwarf_stack_value &t2 = stack[stack.size () - 2]; + std::swap (t1, t2); goto no_push; } @@ -946,23 +915,21 @@ dwarf_expr_context::execute_stack_op (const gdb_byte *op_ptr, case DW_OP_rot: { - struct dwarf_stack_value t1, t2, t3; - - if (this->stack_len < 3) + if (stack.size () < 3) error (_("Not enough elements for " - "DW_OP_rot. Need 3, have %d."), - this->stack_len); - t1 = this->stack[this->stack_len - 1]; - t2 = this->stack[this->stack_len - 2]; - t3 = this->stack[this->stack_len - 3]; - this->stack[this->stack_len - 1] = t2; - this->stack[this->stack_len - 2] = t3; - this->stack[this->stack_len - 3] = t1; + "DW_OP_rot. Need 3, have %zu."), + stack.size ()); + + dwarf_stack_value temp = stack[stack.size () - 1]; + stack[stack.size () - 1] = stack[stack.size () - 2]; + stack[stack.size () - 2] = stack[stack.size () - 3]; + stack[stack.size () - 3] = temp; goto no_push; } case DW_OP_deref: case DW_OP_deref_size: + case DW_OP_deref_type: case DW_OP_GNU_deref_type: { int addr_size = (op == DW_OP_deref ? this->addr_size : *op_ptr++); @@ -972,13 +939,11 @@ dwarf_expr_context::execute_stack_op (const gdb_byte *op_ptr, pop (); - if (op == DW_OP_GNU_deref_type) + if (op == DW_OP_deref_type || 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 = get_base_type (type_die, 0); + cu_offset type_die_cu_off = (cu_offset) uoffset; + type = get_base_type (type_die_cu_off, 0); } else type = address_type; @@ -989,12 +954,12 @@ dwarf_expr_context::execute_stack_op (const gdb_byte *op_ptr, from the type length, we need to zero-extend it. */ if (TYPE_LENGTH (type) != addr_size) { - ULONGEST result = + ULONGEST datum = 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); + byte_order, datum); } result_val = value_from_contents_and_address (type, buf, addr); @@ -1194,7 +1159,7 @@ dwarf_expr_context::execute_stack_op (const gdb_byte *op_ptr, case DW_OP_call_frame_cfa: result = this->get_frame_cfa (); result_val = value_from_ulongest (address_type, result); - in_stack_memory = 1; + in_stack_memory = true; break; case DW_OP_GNU_push_tls_address: @@ -1255,12 +1220,12 @@ dwarf_expr_context::execute_stack_op (const gdb_byte *op_ptr, case DW_OP_bit_piece: { - uint64_t size, offset; + uint64_t size, uleb_offset; /* Record the piece. */ op_ptr = safe_read_uleb128 (op_ptr, op_end, &size); - op_ptr = safe_read_uleb128 (op_ptr, op_end, &offset); - add_piece (size, offset); + op_ptr = safe_read_uleb128 (op_ptr, op_end, &uleb_offset); + add_piece (size, uleb_offset); /* Pop off the address/regnum, and reset the location type. */ @@ -1281,24 +1246,34 @@ dwarf_expr_context::execute_stack_op (const gdb_byte *op_ptr, case DW_OP_call2: { - cu_offset offset; - - offset.cu_off = extract_unsigned_integer (op_ptr, 2, byte_order); + cu_offset cu_off + = (cu_offset) extract_unsigned_integer (op_ptr, 2, byte_order); op_ptr += 2; - this->dwarf_call (offset); + this->dwarf_call (cu_off); } goto no_push; case DW_OP_call4: { - cu_offset offset; - - offset.cu_off = extract_unsigned_integer (op_ptr, 4, byte_order); + cu_offset cu_off + = (cu_offset) extract_unsigned_integer (op_ptr, 4, byte_order); op_ptr += 4; - this->dwarf_call (offset); + this->dwarf_call (cu_off); } goto no_push; + + case DW_OP_GNU_variable_value: + { + sect_offset sect_off + = (sect_offset) extract_unsigned_integer (op_ptr, + this->ref_addr_size, + byte_order); + op_ptr += this->ref_addr_size; + result_val = this->dwarf_variable_value (sect_off); + } + break; + case DW_OP_entry_value: case DW_OP_GNU_entry_value: { uint64_t len; @@ -1307,7 +1282,7 @@ dwarf_expr_context::execute_stack_op (const gdb_byte *op_ptr, 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.")); + error (_("DW_OP_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) @@ -1332,7 +1307,7 @@ dwarf_expr_context::execute_stack_op (const gdb_byte *op_ptr, goto no_push; } - error (_("DWARF-2 expression error: DW_OP_GNU_entry_value is " + error (_("DWARF-2 expression error: DW_OP_entry_value is " "supported only for single DW_OP_reg* " "or for DW_OP_breg*(0)+DW_OP_deref*")); } @@ -1341,8 +1316,8 @@ dwarf_expr_context::execute_stack_op (const gdb_byte *op_ptr, { union call_site_parameter_u kind_u; - kind_u.param_offset.cu_off = extract_unsigned_integer (op_ptr, 4, - byte_order); + kind_u.param_cu_off + = (cu_offset) extract_unsigned_integer (op_ptr, 4, byte_order); op_ptr += 4; this->push_dwarf_reg_entry_value (CALL_SITE_PARAMETER_PARAM_OFFSET, kind_u, @@ -1350,56 +1325,58 @@ dwarf_expr_context::execute_stack_op (const gdb_byte *op_ptr, } goto no_push; + case DW_OP_const_type: 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; + cu_offset type_die_cu_off = (cu_offset) uoffset; + n = *op_ptr++; data = op_ptr; op_ptr += n; - type = get_base_type (type_die, n); + type = get_base_type (type_die_cu_off, n); result_val = value_from_contents (type, data); } break; + case DW_OP_regval_type: 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; + cu_offset type_die_cu_off = (cu_offset) uoffset; - type = get_base_type (type_die, 0); + type = get_base_type (type_die_cu_off, 0); result_val = this->get_reg_value (type, reg); } break; + case DW_OP_convert: case DW_OP_GNU_convert: + case DW_OP_reinterpret: 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; + cu_offset type_die_cu_off = (cu_offset) uoffset; - if (type_die.cu_off == 0) + if (to_underlying (type_die_cu_off) == 0) type = address_type; else - type = get_base_type (type_die, 0); + type = get_base_type (type_die_cu_off, 0); result_val = fetch (0); pop (); - if (op == DW_OP_GNU_convert) + if (op == DW_OP_convert || op == DW_OP_GNU_convert) result_val = value_cast (type, result_val); else if (type == value_type (result_val)) { @@ -1407,7 +1384,7 @@ dwarf_expr_context::execute_stack_op (const gdb_byte *op_ptr, } else if (TYPE_LENGTH (type) != TYPE_LENGTH (value_type (result_val))) - error (_("DW_OP_GNU_reinterpret has wrong size")); + error (_("DW_OP_reinterpret has wrong size")); else result_val = value_from_contents (type, @@ -1438,14 +1415,10 @@ dwarf_expr_context::execute_stack_op (const gdb_byte *op_ptr, if (this->location == DWARF_VALUE_IMPLICIT_POINTER) add_piece (8 * this->addr_size, 0); -abort_expression: this->recursion_depth--; gdb_assert (this->recursion_depth >= 0); } -/* Provide a prototype to silence -Wmissing-prototypes. */ -extern initialize_file_ftype _initialize_dwarf2expr; - void _initialize_dwarf2expr (void) {