+ if (VEC_empty (call_sitep, chain))
+ call_site = NULL;
+ else
+ call_site = VEC_last (call_sitep, chain);
+ }
+
+ if (retval == NULL)
+ {
+ struct minimal_symbol *msym_caller, *msym_callee;
+
+ msym_caller = lookup_minimal_symbol_by_pc (caller_pc);
+ msym_callee = lookup_minimal_symbol_by_pc (callee_pc);
+ throw_error (NO_ENTRY_VALUE_ERROR,
+ _("There are no unambiguously determinable intermediate "
+ "callers or callees between caller function \"%s\" at %s "
+ "and callee function \"%s\" at %s"),
+ (msym_caller == NULL
+ ? "???" : SYMBOL_PRINT_NAME (msym_caller)),
+ paddress (gdbarch, caller_pc),
+ (msym_callee == NULL
+ ? "???" : SYMBOL_PRINT_NAME (msym_callee)),
+ paddress (gdbarch, callee_pc));
+ }
+
+ do_cleanups (back_to_workdata);
+ discard_cleanups (back_to_retval);
+ return retval;
+}
+
+/* Create and return call_site_chain for CALLER_PC and CALLEE_PC. All the
+ assumed frames between them use GDBARCH. If valid call_site_chain cannot be
+ constructed return NULL. Caller is responsible for xfree of the returned
+ result. */
+
+struct call_site_chain *
+call_site_find_chain (struct gdbarch *gdbarch, CORE_ADDR caller_pc,
+ CORE_ADDR callee_pc)
+{
+ volatile struct gdb_exception e;
+ struct call_site_chain *retval = NULL;
+
+ TRY_CATCH (e, RETURN_MASK_ERROR)
+ {
+ retval = call_site_find_chain_1 (gdbarch, caller_pc, callee_pc);
+ }
+ if (e.reason < 0)
+ {
+ if (e.error == NO_ENTRY_VALUE_ERROR)
+ {
+ if (entry_values_debug)
+ exception_print (gdb_stdout, e);
+
+ return NULL;
+ }
+ else
+ throw_exception (e);
+ }
+ return retval;
+}
+
+/* Return 1 if KIND and KIND_U match PARAMETER. Return 0 otherwise. */
+
+static int
+call_site_parameter_matches (struct call_site_parameter *parameter,
+ enum call_site_parameter_kind kind,
+ union call_site_parameter_u kind_u)
+{
+ if (kind == parameter->kind)
+ switch (kind)
+ {
+ case CALL_SITE_PARAMETER_DWARF_REG:
+ return kind_u.dwarf_reg == parameter->u.dwarf_reg;
+ case CALL_SITE_PARAMETER_FB_OFFSET:
+ return kind_u.fb_offset == parameter->u.fb_offset;
+ case CALL_SITE_PARAMETER_PARAM_OFFSET:
+ return kind_u.param_offset.cu_off == parameter->u.param_offset.cu_off;
+ }
+ return 0;
+}
+
+/* Fetch call_site_parameter from caller matching KIND and KIND_U.
+ FRAME is for callee.
+
+ Function always returns non-NULL, it throws NO_ENTRY_VALUE_ERROR
+ otherwise. */
+
+static struct call_site_parameter *
+dwarf_expr_reg_to_entry_parameter (struct frame_info *frame,
+ enum call_site_parameter_kind kind,
+ union call_site_parameter_u kind_u,
+ struct dwarf2_per_cu_data **per_cu_return)
+{
+ CORE_ADDR func_addr = get_frame_func (frame);
+ CORE_ADDR caller_pc;
+ struct gdbarch *gdbarch = get_frame_arch (frame);
+ struct frame_info *caller_frame = get_prev_frame (frame);
+ struct call_site *call_site;
+ int iparams;
+ /* Initialize it just to avoid a GCC false warning. */
+ struct call_site_parameter *parameter = NULL;
+ CORE_ADDR target_addr;
+
+ if (gdbarch != frame_unwind_arch (frame))
+ {
+ struct minimal_symbol *msym = lookup_minimal_symbol_by_pc (func_addr);
+ struct gdbarch *caller_gdbarch = frame_unwind_arch (frame);
+
+ throw_error (NO_ENTRY_VALUE_ERROR,
+ _("DW_OP_GNU_entry_value resolving callee gdbarch %s "
+ "(of %s (%s)) does not match caller gdbarch %s"),
+ gdbarch_bfd_arch_info (gdbarch)->printable_name,
+ paddress (gdbarch, func_addr),
+ msym == NULL ? "???" : SYMBOL_PRINT_NAME (msym),
+ gdbarch_bfd_arch_info (caller_gdbarch)->printable_name);
+ }
+
+ if (caller_frame == NULL)
+ {
+ struct minimal_symbol *msym = lookup_minimal_symbol_by_pc (func_addr);
+
+ throw_error (NO_ENTRY_VALUE_ERROR, _("DW_OP_GNU_entry_value resolving "
+ "requires caller of %s (%s)"),
+ paddress (gdbarch, func_addr),
+ msym == NULL ? "???" : SYMBOL_PRINT_NAME (msym));
+ }
+ caller_pc = get_frame_pc (caller_frame);
+ call_site = call_site_for_pc (gdbarch, caller_pc);
+
+ target_addr = call_site_to_target_addr (gdbarch, call_site, caller_frame);
+ if (target_addr != func_addr)
+ {
+ struct minimal_symbol *target_msym, *func_msym;
+
+ target_msym = lookup_minimal_symbol_by_pc (target_addr);
+ func_msym = lookup_minimal_symbol_by_pc (func_addr);
+ throw_error (NO_ENTRY_VALUE_ERROR,
+ _("DW_OP_GNU_entry_value resolving expects callee %s at %s "
+ "but the called frame is for %s at %s"),
+ (target_msym == NULL ? "???"
+ : SYMBOL_PRINT_NAME (target_msym)),
+ paddress (gdbarch, target_addr),
+ func_msym == NULL ? "???" : SYMBOL_PRINT_NAME (func_msym),
+ paddress (gdbarch, func_addr));
+ }
+
+ /* No entry value based parameters would be reliable if this function can
+ call itself via tail calls. */
+ func_verify_no_selftailcall (gdbarch, func_addr);
+
+ for (iparams = 0; iparams < call_site->parameter_count; iparams++)
+ {
+ parameter = &call_site->parameter[iparams];
+ if (call_site_parameter_matches (parameter, kind, kind_u))
+ break;
+ }
+ if (iparams == call_site->parameter_count)
+ {
+ struct minimal_symbol *msym = lookup_minimal_symbol_by_pc (caller_pc);
+
+ /* DW_TAG_GNU_call_site_parameter will be missing just if GCC could not
+ determine its value. */
+ throw_error (NO_ENTRY_VALUE_ERROR, _("Cannot find matching parameter "
+ "at DW_TAG_GNU_call_site %s at %s"),
+ paddress (gdbarch, caller_pc),
+ msym == NULL ? "???" : SYMBOL_PRINT_NAME (msym));
+ }
+
+ *per_cu_return = call_site->per_cu;
+ return parameter;
+}
+
+/* Return value for PARAMETER matching DEREF_SIZE. If DEREF_SIZE is -1, return
+ the normal DW_AT_GNU_call_site_value block. Otherwise return the
+ DW_AT_GNU_call_site_data_value (dereferenced) block.
+
+ TYPE and CALLER_FRAME specify how to evaluate the DWARF block into returned
+ struct value.
+
+ Function always returns non-NULL, non-optimized out value. It throws
+ NO_ENTRY_VALUE_ERROR if it cannot resolve the value for any reason. */
+
+static struct value *
+dwarf_entry_parameter_to_value (struct call_site_parameter *parameter,
+ CORE_ADDR deref_size, struct type *type,
+ struct frame_info *caller_frame,
+ struct dwarf2_per_cu_data *per_cu)
+{
+ const gdb_byte *data_src;
+ gdb_byte *data;
+ size_t size;
+
+ data_src = deref_size == -1 ? parameter->value : parameter->data_value;
+ size = deref_size == -1 ? parameter->value_size : parameter->data_value_size;
+
+ /* DEREF_SIZE size is not verified here. */
+ if (data_src == NULL)
+ throw_error (NO_ENTRY_VALUE_ERROR,
+ _("Cannot resolve DW_AT_GNU_call_site_data_value"));
+
+ /* DW_AT_GNU_call_site_value is a DWARF expression, not a DWARF
+ location. Postprocessing of DWARF_VALUE_MEMORY would lose the type from
+ DWARF block. */
+ data = alloca (size + 1);
+ memcpy (data, data_src, size);
+ data[size] = DW_OP_stack_value;
+
+ return dwarf2_evaluate_loc_desc (type, caller_frame, data, size + 1, per_cu);
+}
+
+/* Execute DWARF block of call_site_parameter which matches KIND and KIND_U.
+ Choose DEREF_SIZE value of that parameter. Search caller of the CTX's
+ frame. CTX must be of dwarf_expr_ctx_funcs kind.
+
+ The CTX caller can be from a different CU - per_cu_dwarf_call implementation
+ can be more simple as it does not support cross-CU DWARF executions. */
+
+static void
+dwarf_expr_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)
+{
+ struct dwarf_expr_baton *debaton;
+ struct frame_info *frame, *caller_frame;
+ struct dwarf2_per_cu_data *caller_per_cu;
+ struct dwarf_expr_baton baton_local;
+ struct dwarf_expr_context saved_ctx;
+ struct call_site_parameter *parameter;
+ const gdb_byte *data_src;
+ size_t size;
+
+ gdb_assert (ctx->funcs == &dwarf_expr_ctx_funcs);
+ debaton = ctx->baton;
+ frame = debaton->frame;
+ caller_frame = get_prev_frame (frame);
+
+ parameter = dwarf_expr_reg_to_entry_parameter (frame, kind, kind_u,
+ &caller_per_cu);
+ data_src = deref_size == -1 ? parameter->value : parameter->data_value;
+ size = deref_size == -1 ? parameter->value_size : parameter->data_value_size;
+
+ /* DEREF_SIZE size is not verified here. */
+ if (data_src == NULL)
+ throw_error (NO_ENTRY_VALUE_ERROR,
+ _("Cannot resolve DW_AT_GNU_call_site_data_value"));
+
+ baton_local.frame = caller_frame;
+ baton_local.per_cu = caller_per_cu;
+
+ saved_ctx.gdbarch = ctx->gdbarch;
+ saved_ctx.addr_size = ctx->addr_size;
+ saved_ctx.offset = ctx->offset;
+ saved_ctx.baton = ctx->baton;
+ ctx->gdbarch = get_objfile_arch (dwarf2_per_cu_objfile (baton_local.per_cu));
+ ctx->addr_size = dwarf2_per_cu_addr_size (baton_local.per_cu);
+ ctx->offset = dwarf2_per_cu_text_offset (baton_local.per_cu);
+ ctx->baton = &baton_local;
+
+ dwarf_expr_eval (ctx, data_src, size);
+
+ ctx->gdbarch = saved_ctx.gdbarch;
+ ctx->addr_size = saved_ctx.addr_size;
+ ctx->offset = saved_ctx.offset;
+ ctx->baton = saved_ctx.baton;
+}
+
+/* Callback function for dwarf2_evaluate_loc_desc.
+ Fetch the address indexed by DW_OP_GNU_addr_index. */
+
+static CORE_ADDR
+dwarf_expr_get_addr_index (void *baton, unsigned int index)
+{
+ struct dwarf_expr_baton *debaton = (struct dwarf_expr_baton *) baton;
+
+ return dwarf2_read_addr_index (debaton->per_cu, index);
+}
+
+/* VALUE must be of type lval_computed with entry_data_value_funcs. Perform
+ the indirect method on it, that is use its stored target value, the sole
+ purpose of entry_data_value_funcs.. */
+
+static struct value *
+entry_data_value_coerce_ref (const struct value *value)
+{
+ struct type *checked_type = check_typedef (value_type (value));
+ struct value *target_val;
+
+ if (TYPE_CODE (checked_type) != TYPE_CODE_REF)
+ return NULL;
+
+ target_val = value_computed_closure (value);
+ value_incref (target_val);
+ return target_val;
+}
+
+/* Implement copy_closure. */
+
+static void *
+entry_data_value_copy_closure (const struct value *v)
+{
+ struct value *target_val = value_computed_closure (v);
+
+ value_incref (target_val);
+ return target_val;
+}
+
+/* Implement free_closure. */
+
+static void
+entry_data_value_free_closure (struct value *v)
+{
+ struct value *target_val = value_computed_closure (v);
+
+ value_free (target_val);
+}
+
+/* Vector for methods for an entry value reference where the referenced value
+ is stored in the caller. On the first dereference use
+ DW_AT_GNU_call_site_data_value in the caller. */
+
+static const struct lval_funcs entry_data_value_funcs =
+{
+ NULL, /* read */
+ NULL, /* write */
+ NULL, /* check_validity */
+ NULL, /* check_any_valid */
+ NULL, /* indirect */
+ entry_data_value_coerce_ref,
+ NULL, /* check_synthetic_pointer */
+ entry_data_value_copy_closure,
+ entry_data_value_free_closure
+};
+
+/* Read parameter of TYPE at (callee) FRAME's function entry. KIND and KIND_U
+ are used to match DW_AT_location at the caller's
+ DW_TAG_GNU_call_site_parameter.
+
+ Function always returns non-NULL value. It throws NO_ENTRY_VALUE_ERROR if it
+ cannot resolve the parameter for any reason. */
+
+static struct value *
+value_of_dwarf_reg_entry (struct type *type, struct frame_info *frame,
+ enum call_site_parameter_kind kind,
+ union call_site_parameter_u kind_u)
+{
+ struct type *checked_type = check_typedef (type);
+ struct type *target_type = TYPE_TARGET_TYPE (checked_type);
+ struct frame_info *caller_frame = get_prev_frame (frame);
+ struct value *outer_val, *target_val, *val;
+ struct call_site_parameter *parameter;
+ struct dwarf2_per_cu_data *caller_per_cu;
+ CORE_ADDR addr;
+
+ parameter = dwarf_expr_reg_to_entry_parameter (frame, kind, kind_u,
+ &caller_per_cu);
+
+ outer_val = dwarf_entry_parameter_to_value (parameter, -1 /* deref_size */,
+ type, caller_frame,
+ caller_per_cu);
+
+ /* Check if DW_AT_GNU_call_site_data_value cannot be used. If it should be
+ used and it is not available do not fall back to OUTER_VAL - dereferencing
+ TYPE_CODE_REF with non-entry data value would give current value - not the
+ entry value. */
+
+ if (TYPE_CODE (checked_type) != TYPE_CODE_REF
+ || TYPE_TARGET_TYPE (checked_type) == NULL)
+ return outer_val;
+
+ target_val = dwarf_entry_parameter_to_value (parameter,
+ TYPE_LENGTH (target_type),
+ target_type, caller_frame,
+ caller_per_cu);
+
+ /* value_as_address dereferences TYPE_CODE_REF. */
+ addr = extract_typed_address (value_contents (outer_val), checked_type);
+
+ /* The target entry value has artificial address of the entry value
+ reference. */
+ VALUE_LVAL (target_val) = lval_memory;
+ set_value_address (target_val, addr);
+
+ release_value (target_val);
+ val = allocate_computed_value (type, &entry_data_value_funcs,
+ target_val /* closure */);
+
+ /* Copy the referencing pointer to the new computed value. */
+ memcpy (value_contents_raw (val), value_contents_raw (outer_val),
+ TYPE_LENGTH (checked_type));
+ set_value_lazy (val, 0);
+
+ return val;
+}
+
+/* Read parameter of TYPE at (callee) FRAME's function entry. DATA and
+ SIZE are DWARF block used to match DW_AT_location at the caller's
+ DW_TAG_GNU_call_site_parameter.
+
+ Function always returns non-NULL value. It throws NO_ENTRY_VALUE_ERROR if it
+ cannot resolve the parameter for any reason. */
+
+static struct value *
+value_of_dwarf_block_entry (struct type *type, struct frame_info *frame,
+ const gdb_byte *block, size_t block_len)
+{
+ union call_site_parameter_u kind_u;
+
+ kind_u.dwarf_reg = dwarf_block_to_dwarf_reg (block, block + block_len);
+ if (kind_u.dwarf_reg != -1)
+ return value_of_dwarf_reg_entry (type, frame, CALL_SITE_PARAMETER_DWARF_REG,
+ kind_u);
+
+ if (dwarf_block_to_fb_offset (block, block + block_len, &kind_u.fb_offset))
+ return value_of_dwarf_reg_entry (type, frame, CALL_SITE_PARAMETER_FB_OFFSET,
+ kind_u);
+
+ /* This can normally happen - throw NO_ENTRY_VALUE_ERROR to get the message
+ suppressed during normal operation. The expression can be arbitrary if
+ there is no caller-callee entry value binding expected. */
+ throw_error (NO_ENTRY_VALUE_ERROR,
+ _("DWARF-2 expression error: DW_OP_GNU_entry_value is supported "
+ "only for single DW_OP_reg* or for DW_OP_fbreg(*)"));
+}
+
+struct piece_closure
+{
+ /* Reference count. */
+ int refc;
+
+ /* The CU from which this closure's expression came. */
+ struct dwarf2_per_cu_data *per_cu;
+
+ /* The number of pieces used to describe this variable. */
+ int n_pieces;
+
+ /* The target address size, used only for DWARF_VALUE_STACK. */
+ int addr_size;
+
+ /* The pieces themselves. */
+ struct dwarf_expr_piece *pieces;
+};
+
+/* Allocate a closure for a value formed from separately-described
+ PIECES. */
+
+static struct piece_closure *
+allocate_piece_closure (struct dwarf2_per_cu_data *per_cu,
+ int n_pieces, struct dwarf_expr_piece *pieces,
+ int addr_size)
+{
+ struct piece_closure *c = XZALLOC (struct piece_closure);
+ int i;
+
+ c->refc = 1;
+ c->per_cu = per_cu;
+ c->n_pieces = n_pieces;
+ c->addr_size = addr_size;
+ c->pieces = XCALLOC (n_pieces, struct dwarf_expr_piece);
+
+ memcpy (c->pieces, pieces, n_pieces * sizeof (struct dwarf_expr_piece));
+ for (i = 0; i < n_pieces; ++i)
+ if (c->pieces[i].location == DWARF_VALUE_STACK)
+ value_incref (c->pieces[i].v.value);
+
+ return c;
+}
+
+/* The lowest-level function to extract bits from a byte buffer.
+ SOURCE is the buffer. It is updated if we read to the end of a
+ byte.
+ SOURCE_OFFSET_BITS is the offset of the first bit to read. It is
+ updated to reflect the number of bits actually read.
+ NBITS is the number of bits we want to read. It is updated to
+ reflect the number of bits actually read. This function may read
+ fewer bits.
+ BITS_BIG_ENDIAN is taken directly from gdbarch.
+ This function returns the extracted bits. */
+
+static unsigned int
+extract_bits_primitive (const gdb_byte **source,
+ unsigned int *source_offset_bits,
+ int *nbits, int bits_big_endian)
+{
+ unsigned int avail, mask, datum;
+
+ gdb_assert (*source_offset_bits < 8);
+
+ avail = 8 - *source_offset_bits;
+ if (avail > *nbits)
+ avail = *nbits;
+
+ mask = (1 << avail) - 1;
+ datum = **source;
+ if (bits_big_endian)
+ datum >>= 8 - (*source_offset_bits + *nbits);
+ else
+ datum >>= *source_offset_bits;
+ datum &= mask;
+
+ *nbits -= avail;
+ *source_offset_bits += avail;
+ if (*source_offset_bits >= 8)
+ {
+ *source_offset_bits -= 8;
+ ++*source;
+ }
+
+ return datum;
+}
+
+/* Extract some bits from a source buffer and move forward in the
+ buffer.
+
+ SOURCE is the source buffer. It is updated as bytes are read.
+ SOURCE_OFFSET_BITS is the offset into SOURCE. It is updated as
+ bits are read.
+ NBITS is the number of bits to read.
+ BITS_BIG_ENDIAN is taken directly from gdbarch.
+
+ This function returns the bits that were read. */
+
+static unsigned int
+extract_bits (const gdb_byte **source, unsigned int *source_offset_bits,
+ int nbits, int bits_big_endian)
+{
+ unsigned int datum;
+
+ gdb_assert (nbits > 0 && nbits <= 8);
+
+ datum = extract_bits_primitive (source, source_offset_bits, &nbits,
+ bits_big_endian);
+ if (nbits > 0)
+ {
+ unsigned int more;
+
+ more = extract_bits_primitive (source, source_offset_bits, &nbits,
+ bits_big_endian);
+ if (bits_big_endian)
+ datum <<= nbits;
+ else
+ more <<= nbits;
+ datum |= more;
+ }
+
+ return datum;
+}
+
+/* Write some bits into a buffer and move forward in the buffer.
+
+ DATUM is the bits to write. The low-order bits of DATUM are used.
+ DEST is the destination buffer. It is updated as bytes are
+ written.
+ DEST_OFFSET_BITS is the bit offset in DEST at which writing is
+ done.
+ NBITS is the number of valid bits in DATUM.
+ BITS_BIG_ENDIAN is taken directly from gdbarch. */
+
+static void
+insert_bits (unsigned int datum,
+ gdb_byte *dest, unsigned int dest_offset_bits,
+ int nbits, int bits_big_endian)
+{
+ unsigned int mask;
+
+ gdb_assert (dest_offset_bits + nbits <= 8);
+
+ mask = (1 << nbits) - 1;
+ if (bits_big_endian)
+ {
+ datum <<= 8 - (dest_offset_bits + nbits);
+ mask <<= 8 - (dest_offset_bits + nbits);
+ }
+ else
+ {
+ datum <<= dest_offset_bits;
+ mask <<= dest_offset_bits;
+ }
+
+ gdb_assert ((datum & ~mask) == 0);
+
+ *dest = (*dest & ~mask) | datum;
+}
+
+/* Copy bits from a source to a destination.
+
+ DEST is where the bits should be written.
+ DEST_OFFSET_BITS is the bit offset into DEST.
+ SOURCE is the source of bits.
+ SOURCE_OFFSET_BITS is the bit offset into SOURCE.
+ BIT_COUNT is the number of bits to copy.
+ BITS_BIG_ENDIAN is taken directly from gdbarch. */
+
+static void
+copy_bitwise (gdb_byte *dest, unsigned int dest_offset_bits,
+ const gdb_byte *source, unsigned int source_offset_bits,
+ unsigned int bit_count,
+ int bits_big_endian)
+{
+ unsigned int dest_avail;
+ int datum;
+
+ /* Reduce everything to byte-size pieces. */
+ dest += dest_offset_bits / 8;
+ dest_offset_bits %= 8;
+ source += source_offset_bits / 8;
+ source_offset_bits %= 8;
+
+ dest_avail = 8 - dest_offset_bits % 8;
+
+ /* See if we can fill the first destination byte. */
+ if (dest_avail < bit_count)
+ {
+ datum = extract_bits (&source, &source_offset_bits, dest_avail,
+ bits_big_endian);
+ insert_bits (datum, dest, dest_offset_bits, dest_avail, bits_big_endian);
+ ++dest;
+ dest_offset_bits = 0;
+ bit_count -= dest_avail;
+ }
+
+ /* Now, either DEST_OFFSET_BITS is byte-aligned, or we have fewer
+ than 8 bits remaining. */
+ gdb_assert (dest_offset_bits % 8 == 0 || bit_count < 8);
+ for (; bit_count >= 8; bit_count -= 8)
+ {
+ datum = extract_bits (&source, &source_offset_bits, 8, bits_big_endian);
+ *dest++ = (gdb_byte) datum;
+ }
+
+ /* Finally, we may have a few leftover bits. */
+ gdb_assert (bit_count <= 8 - dest_offset_bits % 8);
+ if (bit_count > 0)
+ {
+ datum = extract_bits (&source, &source_offset_bits, bit_count,
+ bits_big_endian);
+ insert_bits (datum, dest, dest_offset_bits, bit_count, bits_big_endian);
+ }
+}
+
+static void
+read_pieced_value (struct value *v)
+{
+ int i;
+ long offset = 0;
+ ULONGEST bits_to_skip;
+ gdb_byte *contents;
+ struct piece_closure *c
+ = (struct piece_closure *) value_computed_closure (v);
+ struct frame_info *frame = frame_find_by_id (VALUE_FRAME_ID (v));
+ size_t type_len;
+ size_t buffer_size = 0;
+ char *buffer = NULL;
+ struct cleanup *cleanup;
+ int bits_big_endian
+ = gdbarch_bits_big_endian (get_type_arch (value_type (v)));
+
+ if (value_type (v) != value_enclosing_type (v))
+ internal_error (__FILE__, __LINE__,
+ _("Should not be able to create a lazy value with "
+ "an enclosing type"));
+
+ cleanup = make_cleanup (free_current_contents, &buffer);
+
+ contents = value_contents_raw (v);
+ bits_to_skip = 8 * value_offset (v);
+ if (value_bitsize (v))
+ {
+ bits_to_skip += value_bitpos (v);
+ type_len = value_bitsize (v);
+ }
+ else
+ type_len = 8 * TYPE_LENGTH (value_type (v));
+
+ for (i = 0; i < c->n_pieces && offset < type_len; i++)
+ {
+ struct dwarf_expr_piece *p = &c->pieces[i];
+ size_t this_size, this_size_bits;
+ long dest_offset_bits, source_offset_bits, source_offset;
+ const gdb_byte *intermediate_buffer;
+
+ /* Compute size, source, and destination offsets for copying, in
+ bits. */
+ this_size_bits = p->size;
+ if (bits_to_skip > 0 && bits_to_skip >= this_size_bits)
+ {
+ bits_to_skip -= this_size_bits;
+ continue;
+ }
+ if (this_size_bits > type_len - offset)
+ this_size_bits = type_len - offset;
+ if (bits_to_skip > 0)
+ {
+ dest_offset_bits = 0;
+ source_offset_bits = bits_to_skip;
+ this_size_bits -= bits_to_skip;
+ bits_to_skip = 0;
+ }
+ else
+ {
+ dest_offset_bits = offset;
+ source_offset_bits = 0;
+ }
+
+ this_size = (this_size_bits + source_offset_bits % 8 + 7) / 8;
+ source_offset = source_offset_bits / 8;
+ if (buffer_size < this_size)
+ {
+ buffer_size = this_size;
+ buffer = xrealloc (buffer, buffer_size);
+ }
+ intermediate_buffer = buffer;
+
+ /* Copy from the source to DEST_BUFFER. */
+ switch (p->location)
+ {
+ case DWARF_VALUE_REGISTER:
+ {
+ struct gdbarch *arch = get_frame_arch (frame);
+ int gdb_regnum = gdbarch_dwarf2_reg_to_regnum (arch, p->v.regno);
+ int reg_offset = source_offset;
+
+ if (gdbarch_byte_order (arch) == BFD_ENDIAN_BIG
+ && this_size < register_size (arch, gdb_regnum))
+ {
+ /* Big-endian, and we want less than full size. */
+ reg_offset = register_size (arch, gdb_regnum) - this_size;
+ /* We want the lower-order THIS_SIZE_BITS of the bytes
+ we extract from the register. */
+ source_offset_bits += 8 * this_size - this_size_bits;
+ }
+
+ if (gdb_regnum != -1)
+ {
+ int optim, unavail;
+
+ if (!get_frame_register_bytes (frame, gdb_regnum, reg_offset,
+ this_size, buffer,
+ &optim, &unavail))
+ {
+ /* Just so garbage doesn't ever shine through. */
+ memset (buffer, 0, this_size);
+
+ if (optim)
+ set_value_optimized_out (v, 1);
+ if (unavail)
+ mark_value_bytes_unavailable (v, offset, this_size);
+ }
+ }
+ else
+ {
+ error (_("Unable to access DWARF register number %s"),
+ paddress (arch, p->v.regno));
+ }
+ }
+ break;
+
+ case DWARF_VALUE_MEMORY:
+ read_value_memory (v, offset,
+ p->v.mem.in_stack_memory,
+ p->v.mem.addr + source_offset,
+ buffer, this_size);
+ break;
+
+ case DWARF_VALUE_STACK:
+ {
+ size_t n = this_size;
+
+ if (n > c->addr_size - source_offset)
+ n = (c->addr_size >= source_offset
+ ? c->addr_size - source_offset
+ : 0);
+ if (n == 0)
+ {
+ /* Nothing. */
+ }
+ else
+ {
+ const gdb_byte *val_bytes = value_contents_all (p->v.value);
+
+ intermediate_buffer = val_bytes + source_offset;
+ }
+ }
+ break;
+
+ case DWARF_VALUE_LITERAL:
+ {
+ size_t n = this_size;
+
+ if (n > p->v.literal.length - source_offset)
+ n = (p->v.literal.length >= source_offset
+ ? p->v.literal.length - source_offset
+ : 0);
+ if (n != 0)
+ intermediate_buffer = p->v.literal.data + source_offset;
+ }
+ break;
+
+ /* These bits show up as zeros -- but do not cause the value
+ to be considered optimized-out. */
+ case DWARF_VALUE_IMPLICIT_POINTER:
+ break;
+
+ case DWARF_VALUE_OPTIMIZED_OUT:
+ set_value_optimized_out (v, 1);
+ break;
+
+ default:
+ internal_error (__FILE__, __LINE__, _("invalid location type"));
+ }
+
+ if (p->location != DWARF_VALUE_OPTIMIZED_OUT
+ && p->location != DWARF_VALUE_IMPLICIT_POINTER)
+ copy_bitwise (contents, dest_offset_bits,
+ intermediate_buffer, source_offset_bits % 8,
+ this_size_bits, bits_big_endian);
+
+ offset += this_size_bits;
+ }
+
+ do_cleanups (cleanup);
+}
+
+static void
+write_pieced_value (struct value *to, struct value *from)
+{
+ int i;
+ long offset = 0;
+ ULONGEST bits_to_skip;
+ const gdb_byte *contents;
+ struct piece_closure *c
+ = (struct piece_closure *) value_computed_closure (to);
+ struct frame_info *frame = frame_find_by_id (VALUE_FRAME_ID (to));
+ size_t type_len;
+ size_t buffer_size = 0;
+ char *buffer = NULL;
+ struct cleanup *cleanup;
+ int bits_big_endian
+ = gdbarch_bits_big_endian (get_type_arch (value_type (to)));
+
+ if (frame == NULL)
+ {
+ set_value_optimized_out (to, 1);
+ return;
+ }
+
+ cleanup = make_cleanup (free_current_contents, &buffer);
+
+ contents = value_contents (from);
+ bits_to_skip = 8 * value_offset (to);
+ if (value_bitsize (to))
+ {
+ bits_to_skip += value_bitpos (to);
+ type_len = value_bitsize (to);
+ }
+ else
+ type_len = 8 * TYPE_LENGTH (value_type (to));
+
+ for (i = 0; i < c->n_pieces && offset < type_len; i++)
+ {
+ struct dwarf_expr_piece *p = &c->pieces[i];
+ size_t this_size_bits, this_size;
+ long dest_offset_bits, source_offset_bits, dest_offset, source_offset;
+ int need_bitwise;
+ const gdb_byte *source_buffer;
+
+ this_size_bits = p->size;
+ if (bits_to_skip > 0 && bits_to_skip >= this_size_bits)
+ {
+ bits_to_skip -= this_size_bits;
+ continue;
+ }
+ if (this_size_bits > type_len - offset)
+ this_size_bits = type_len - offset;
+ if (bits_to_skip > 0)
+ {
+ dest_offset_bits = bits_to_skip;
+ source_offset_bits = 0;
+ this_size_bits -= bits_to_skip;
+ bits_to_skip = 0;
+ }
+ else
+ {
+ dest_offset_bits = 0;
+ source_offset_bits = offset;
+ }
+
+ this_size = (this_size_bits + source_offset_bits % 8 + 7) / 8;
+ source_offset = source_offset_bits / 8;
+ dest_offset = dest_offset_bits / 8;
+ if (dest_offset_bits % 8 == 0 && source_offset_bits % 8 == 0)
+ {
+ source_buffer = contents + source_offset;
+ need_bitwise = 0;
+ }
+ else
+ {
+ if (buffer_size < this_size)
+ {
+ buffer_size = this_size;
+ buffer = xrealloc (buffer, buffer_size);
+ }
+ source_buffer = buffer;
+ need_bitwise = 1;
+ }
+
+ switch (p->location)
+ {
+ case DWARF_VALUE_REGISTER:
+ {
+ struct gdbarch *arch = get_frame_arch (frame);
+ int gdb_regnum = gdbarch_dwarf2_reg_to_regnum (arch, p->v.regno);
+ int reg_offset = dest_offset;
+
+ if (gdbarch_byte_order (arch) == BFD_ENDIAN_BIG
+ && this_size <= register_size (arch, gdb_regnum))
+ /* Big-endian, and we want less than full size. */
+ reg_offset = register_size (arch, gdb_regnum) - this_size;
+
+ if (gdb_regnum != -1)
+ {
+ if (need_bitwise)
+ {
+ int optim, unavail;
+
+ if (!get_frame_register_bytes (frame, gdb_regnum, reg_offset,
+ this_size, buffer,
+ &optim, &unavail))
+ {
+ if (optim)
+ error (_("Can't do read-modify-write to "
+ "update bitfield; containing word has been "
+ "optimized out"));
+ if (unavail)
+ throw_error (NOT_AVAILABLE_ERROR,
+ _("Can't do read-modify-write to update "
+ "bitfield; containing word "
+ "is unavailable"));
+ }
+ copy_bitwise (buffer, dest_offset_bits,
+ contents, source_offset_bits,
+ this_size_bits,
+ bits_big_endian);
+ }
+
+ put_frame_register_bytes (frame, gdb_regnum, reg_offset,
+ this_size, source_buffer);
+ }
+ else
+ {
+ error (_("Unable to write to DWARF register number %s"),
+ paddress (arch, p->v.regno));
+ }
+ }
+ break;
+ case DWARF_VALUE_MEMORY:
+ if (need_bitwise)
+ {
+ /* Only the first and last bytes can possibly have any
+ bits reused. */
+ read_memory (p->v.mem.addr + dest_offset, buffer, 1);
+ read_memory (p->v.mem.addr + dest_offset + this_size - 1,
+ buffer + this_size - 1, 1);
+ copy_bitwise (buffer, dest_offset_bits,
+ contents, source_offset_bits,
+ this_size_bits,
+ bits_big_endian);
+ }
+
+ write_memory (p->v.mem.addr + dest_offset,
+ source_buffer, this_size);
+ break;
+ default:
+ set_value_optimized_out (to, 1);
+ break;
+ }
+ offset += this_size_bits;
+ }
+
+ do_cleanups (cleanup);
+}
+
+/* A helper function that checks bit validity in a pieced value.
+ CHECK_FOR indicates the kind of validity checking.
+ DWARF_VALUE_MEMORY means to check whether any bit is valid.
+ DWARF_VALUE_OPTIMIZED_OUT means to check whether any bit is
+ optimized out.
+ DWARF_VALUE_IMPLICIT_POINTER means to check whether the bits are an
+ implicit pointer. */
+
+static int
+check_pieced_value_bits (const struct value *value, int bit_offset,
+ int bit_length,
+ enum dwarf_value_location check_for)
+{
+ struct piece_closure *c
+ = (struct piece_closure *) value_computed_closure (value);
+ int i;
+ int validity = (check_for == DWARF_VALUE_MEMORY
+ || check_for == DWARF_VALUE_IMPLICIT_POINTER);
+
+ bit_offset += 8 * value_offset (value);
+ if (value_bitsize (value))
+ bit_offset += value_bitpos (value);
+
+ for (i = 0; i < c->n_pieces && bit_length > 0; i++)
+ {
+ struct dwarf_expr_piece *p = &c->pieces[i];
+ size_t this_size_bits = p->size;
+
+ if (bit_offset > 0)
+ {
+ if (bit_offset >= this_size_bits)
+ {
+ bit_offset -= this_size_bits;
+ continue;
+ }
+
+ bit_length -= this_size_bits - bit_offset;
+ bit_offset = 0;
+ }
+ else
+ bit_length -= this_size_bits;
+
+ if (check_for == DWARF_VALUE_IMPLICIT_POINTER)
+ {
+ if (p->location != DWARF_VALUE_IMPLICIT_POINTER)
+ return 0;
+ }
+ else if (p->location == DWARF_VALUE_OPTIMIZED_OUT
+ || p->location == DWARF_VALUE_IMPLICIT_POINTER)
+ {
+ if (validity)
+ return 0;
+ }
+ else
+ {
+ if (!validity)
+ return 1;
+ }
+ }
+
+ return validity;
+}
+
+static int
+check_pieced_value_validity (const struct value *value, int bit_offset,
+ int bit_length)
+{
+ return check_pieced_value_bits (value, bit_offset, bit_length,
+ DWARF_VALUE_MEMORY);
+}
+
+static int
+check_pieced_value_invalid (const struct value *value)
+{
+ return check_pieced_value_bits (value, 0,
+ 8 * TYPE_LENGTH (value_type (value)),
+ DWARF_VALUE_OPTIMIZED_OUT);
+}
+
+/* An implementation of an lval_funcs method to see whether a value is
+ a synthetic pointer. */
+
+static int
+check_pieced_synthetic_pointer (const struct value *value, int bit_offset,
+ int bit_length)
+{
+ return check_pieced_value_bits (value, bit_offset, bit_length,
+ DWARF_VALUE_IMPLICIT_POINTER);
+}
+
+/* A wrapper function for get_frame_address_in_block. */
+
+static CORE_ADDR
+get_frame_address_in_block_wrapper (void *baton)
+{
+ return get_frame_address_in_block (baton);
+}
+
+/* An implementation of an lval_funcs method to indirect through a
+ pointer. This handles the synthetic pointer case when needed. */
+
+static struct value *
+indirect_pieced_value (struct value *value)
+{
+ struct piece_closure *c
+ = (struct piece_closure *) value_computed_closure (value);
+ struct type *type;
+ struct frame_info *frame;
+ struct dwarf2_locexpr_baton baton;
+ int i, bit_offset, bit_length;
+ struct dwarf_expr_piece *piece = NULL;
+ LONGEST byte_offset;
+
+ type = check_typedef (value_type (value));
+ if (TYPE_CODE (type) != TYPE_CODE_PTR)
+ return NULL;
+
+ bit_length = 8 * TYPE_LENGTH (type);
+ bit_offset = 8 * value_offset (value);
+ if (value_bitsize (value))
+ bit_offset += value_bitpos (value);
+
+ for (i = 0; i < c->n_pieces && bit_length > 0; i++)
+ {
+ struct dwarf_expr_piece *p = &c->pieces[i];
+ size_t this_size_bits = p->size;
+
+ if (bit_offset > 0)
+ {
+ if (bit_offset >= this_size_bits)
+ {
+ bit_offset -= this_size_bits;
+ continue;
+ }
+
+ bit_length -= this_size_bits - bit_offset;
+ bit_offset = 0;
+ }
+ else
+ bit_length -= this_size_bits;
+
+ if (p->location != DWARF_VALUE_IMPLICIT_POINTER)
+ return NULL;
+
+ if (bit_length != 0)
+ error (_("Invalid use of DW_OP_GNU_implicit_pointer"));
+
+ piece = p;
+ break;
+ }
+
+ frame = get_selected_frame (_("No frame selected."));
+
+ /* This is an offset requested by GDB, such as value subcripts. */
+ byte_offset = value_as_address (value);
+
+ gdb_assert (piece);
+ baton = dwarf2_fetch_die_location_block (piece->v.ptr.die, c->per_cu,
+ get_frame_address_in_block_wrapper,
+ frame);
+
+ return dwarf2_evaluate_loc_desc_full (TYPE_TARGET_TYPE (type), frame,
+ baton.data, baton.size, baton.per_cu,
+ piece->v.ptr.offset + byte_offset);
+}
+
+static void *
+copy_pieced_value_closure (const struct value *v)
+{
+ struct piece_closure *c
+ = (struct piece_closure *) value_computed_closure (v);
+
+ ++c->refc;
+ return c;
+}
+
+static void
+free_pieced_value_closure (struct value *v)
+{
+ struct piece_closure *c
+ = (struct piece_closure *) value_computed_closure (v);
+
+ --c->refc;
+ if (c->refc == 0)
+ {
+ int i;
+
+ for (i = 0; i < c->n_pieces; ++i)
+ if (c->pieces[i].location == DWARF_VALUE_STACK)
+ value_free (c->pieces[i].v.value);
+
+ xfree (c->pieces);
+ xfree (c);
+ }
+}
+
+/* Functions for accessing a variable described by DW_OP_piece. */
+static const struct lval_funcs pieced_value_funcs = {
+ read_pieced_value,
+ write_pieced_value,
+ check_pieced_value_validity,
+ check_pieced_value_invalid,
+ indirect_pieced_value,
+ NULL, /* coerce_ref */
+ check_pieced_synthetic_pointer,
+ copy_pieced_value_closure,
+ free_pieced_value_closure
+};
+
+/* Helper function which throws an error if a synthetic pointer is
+ invalid. */
+
+static void
+invalid_synthetic_pointer (void)
+{
+ error (_("access outside bounds of object "
+ "referenced via synthetic pointer"));
+}
+
+/* Virtual method table for dwarf2_evaluate_loc_desc_full below. */
+
+static const struct dwarf_expr_context_funcs dwarf_expr_ctx_funcs =
+{
+ dwarf_expr_read_reg,
+ dwarf_expr_read_mem,
+ dwarf_expr_frame_base,
+ dwarf_expr_frame_cfa,
+ dwarf_expr_frame_pc,
+ dwarf_expr_tls_address,
+ dwarf_expr_dwarf_call,
+ dwarf_expr_get_base_type,
+ dwarf_expr_push_dwarf_reg_entry_value,
+ dwarf_expr_get_addr_index
+};
+
+/* Evaluate a location description, starting at DATA and with length
+ SIZE, to find the current location of variable of TYPE in the
+ context of FRAME. BYTE_OFFSET is applied after the contents are
+ computed. */
+
+static struct value *
+dwarf2_evaluate_loc_desc_full (struct type *type, struct frame_info *frame,
+ const gdb_byte *data, size_t size,
+ struct dwarf2_per_cu_data *per_cu,
+ LONGEST byte_offset)
+{
+ struct value *retval;
+ struct dwarf_expr_baton baton;
+ struct dwarf_expr_context *ctx;
+ struct cleanup *old_chain, *value_chain;
+ struct objfile *objfile = dwarf2_per_cu_objfile (per_cu);
+ volatile struct gdb_exception ex;
+
+ if (byte_offset < 0)
+ invalid_synthetic_pointer ();
+
+ if (size == 0)
+ return allocate_optimized_out_value (type);
+
+ baton.frame = frame;
+ baton.per_cu = per_cu;
+
+ ctx = new_dwarf_expr_context ();
+ old_chain = make_cleanup_free_dwarf_expr_context (ctx);
+ value_chain = make_cleanup_value_free_to_mark (value_mark ());
+
+ ctx->gdbarch = get_objfile_arch (objfile);
+ ctx->addr_size = dwarf2_per_cu_addr_size (per_cu);
+ ctx->ref_addr_size = dwarf2_per_cu_ref_addr_size (per_cu);
+ ctx->offset = dwarf2_per_cu_text_offset (per_cu);
+ ctx->baton = &baton;
+ ctx->funcs = &dwarf_expr_ctx_funcs;
+
+ TRY_CATCH (ex, RETURN_MASK_ERROR)
+ {
+ dwarf_expr_eval (ctx, data, size);
+ }
+ if (ex.reason < 0)
+ {
+ if (ex.error == NOT_AVAILABLE_ERROR)
+ {
+ do_cleanups (old_chain);
+ retval = allocate_value (type);
+ mark_value_bytes_unavailable (retval, 0, TYPE_LENGTH (type));
+ return retval;
+ }
+ else if (ex.error == NO_ENTRY_VALUE_ERROR)
+ {
+ if (entry_values_debug)
+ exception_print (gdb_stdout, ex);
+ do_cleanups (old_chain);
+ return allocate_optimized_out_value (type);
+ }
+ else
+ throw_exception (ex);
+ }
+
+ if (ctx->num_pieces > 0)
+ {
+ struct piece_closure *c;
+ struct frame_id frame_id = get_frame_id (frame);
+ ULONGEST bit_size = 0;
+ int i;
+
+ for (i = 0; i < ctx->num_pieces; ++i)
+ bit_size += ctx->pieces[i].size;
+ if (8 * (byte_offset + TYPE_LENGTH (type)) > bit_size)
+ invalid_synthetic_pointer ();
+
+ c = allocate_piece_closure (per_cu, ctx->num_pieces, ctx->pieces,
+ ctx->addr_size);
+ /* We must clean up the value chain after creating the piece
+ closure but before allocating the result. */
+ do_cleanups (value_chain);
+ retval = allocate_computed_value (type, &pieced_value_funcs, c);
+ VALUE_FRAME_ID (retval) = frame_id;
+ set_value_offset (retval, byte_offset);
+ }
+ else
+ {
+ switch (ctx->location)
+ {
+ case DWARF_VALUE_REGISTER:
+ {
+ struct gdbarch *arch = get_frame_arch (frame);
+ ULONGEST dwarf_regnum = value_as_long (dwarf_expr_fetch (ctx, 0));
+ int gdb_regnum = gdbarch_dwarf2_reg_to_regnum (arch, dwarf_regnum);
+
+ if (byte_offset != 0)
+ error (_("cannot use offset on synthetic pointer to register"));
+ do_cleanups (value_chain);
+ if (gdb_regnum != -1)
+ retval = value_from_register (type, gdb_regnum, frame);
+ else
+ error (_("Unable to access DWARF register number %s"),
+ paddress (arch, dwarf_regnum));
+ }
+ break;
+
+ case DWARF_VALUE_MEMORY:
+ {
+ CORE_ADDR address = dwarf_expr_fetch_address (ctx, 0);
+ int in_stack_memory = dwarf_expr_fetch_in_stack_memory (ctx, 0);
+
+ do_cleanups (value_chain);
+ retval = allocate_value_lazy (type);
+ VALUE_LVAL (retval) = lval_memory;
+ if (in_stack_memory)
+ set_value_stack (retval, 1);
+ set_value_address (retval, address + byte_offset);
+ }
+ break;
+
+ case DWARF_VALUE_STACK:
+ {
+ struct value *value = dwarf_expr_fetch (ctx, 0);
+ gdb_byte *contents;
+ const gdb_byte *val_bytes;
+ size_t n = TYPE_LENGTH (value_type (value));
+
+ if (byte_offset + TYPE_LENGTH (type) > n)
+ invalid_synthetic_pointer ();
+
+ val_bytes = value_contents_all (value);
+ val_bytes += byte_offset;
+ n -= byte_offset;
+
+ /* Preserve VALUE because we are going to free values back
+ to the mark, but we still need the value contents
+ below. */
+ value_incref (value);
+ do_cleanups (value_chain);
+ make_cleanup_value_free (value);
+
+ retval = allocate_value (type);
+ contents = value_contents_raw (retval);
+ if (n > TYPE_LENGTH (type))
+ {
+ struct gdbarch *objfile_gdbarch = get_objfile_arch (objfile);
+
+ if (gdbarch_byte_order (objfile_gdbarch) == BFD_ENDIAN_BIG)
+ val_bytes += n - TYPE_LENGTH (type);
+ n = TYPE_LENGTH (type);
+ }
+ memcpy (contents, val_bytes, n);
+ }
+ break;
+
+ case DWARF_VALUE_LITERAL:
+ {
+ bfd_byte *contents;
+ const bfd_byte *ldata;
+ size_t n = ctx->len;
+
+ if (byte_offset + TYPE_LENGTH (type) > n)
+ invalid_synthetic_pointer ();
+
+ do_cleanups (value_chain);
+ retval = allocate_value (type);
+ contents = value_contents_raw (retval);
+
+ ldata = ctx->data + byte_offset;
+ n -= byte_offset;
+
+ if (n > TYPE_LENGTH (type))
+ {
+ struct gdbarch *objfile_gdbarch = get_objfile_arch (objfile);
+
+ if (gdbarch_byte_order (objfile_gdbarch) == BFD_ENDIAN_BIG)
+ ldata += n - TYPE_LENGTH (type);
+ n = TYPE_LENGTH (type);
+ }
+ memcpy (contents, ldata, n);
+ }
+ break;
+
+ case DWARF_VALUE_OPTIMIZED_OUT:
+ do_cleanups (value_chain);
+ retval = allocate_optimized_out_value (type);
+ break;
+
+ /* DWARF_VALUE_IMPLICIT_POINTER was converted to a pieced
+ operation by execute_stack_op. */
+ case DWARF_VALUE_IMPLICIT_POINTER:
+ /* DWARF_VALUE_OPTIMIZED_OUT can't occur in this context --
+ it can only be encountered when making a piece. */
+ default:
+ internal_error (__FILE__, __LINE__, _("invalid location type"));
+ }
+ }
+
+ set_value_initialized (retval, ctx->initialized);
+
+ do_cleanups (old_chain);