{
struct dwarf_expr_baton *debaton = ctx->baton;
- return per_cu_dwarf_call (ctx, die_offset, debaton->per_cu,
- ctx->get_frame_pc, ctx->baton);
+ per_cu_dwarf_call (ctx, die_offset, debaton->per_cu,
+ ctx->get_frame_pc, ctx->baton);
}
struct piece_closure
{
unsigned int mask;
- gdb_assert (dest_offset_bits >= 0 && dest_offset_bits + nbits <= 8);
+ gdb_assert (dest_offset_bits + nbits <= 8);
mask = (1 << nbits) - 1;
if (bits_big_endian)
if (gdb_regnum != -1)
{
- get_frame_register_bytes (frame, gdb_regnum, reg_offset,
- this_size, buffer);
+ 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
{
{
if (need_bitwise)
{
- get_frame_register_bytes (frame, gdb_regnum, reg_offset,
- this_size, buffer);
+ 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,
frame = get_selected_frame (_("No frame selected."));
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);
struct dwarf_expr_context *ctx;
struct cleanup *old_chain;
struct objfile *objfile = dwarf2_per_cu_objfile (per_cu);
+ volatile struct gdb_exception ex;
if (byte_offset < 0)
invalid_synthetic_pointer ();
ctx->get_tls_address = dwarf_expr_tls_address;
ctx->dwarf_call = dwarf_expr_dwarf_call;
- dwarf_expr_eval (ctx, data, size);
+ TRY_CATCH (ex, RETURN_MASK_ERROR)
+ {
+ dwarf_expr_eval (ctx, data, size);
+ }
+ if (ex.reason < 0)
+ {
+ if (ex.error == NOT_AVAILABLE_ERROR)
+ {
+ retval = allocate_value (type);
+ mark_value_bytes_unavailable (retval, 0, TYPE_LENGTH (type));
+ return retval;
+ }
+ else
+ throw_exception (ex);
+ }
+
if (ctx->num_pieces > 0)
{
struct piece_closure *c;
case DWARF_VALUE_LITERAL:
{
bfd_byte *contents;
- const bfd_byte *data;
+ const bfd_byte *ldata;
size_t n = ctx->len;
if (byte_offset + TYPE_LENGTH (type) > n)
retval = allocate_value (type);
contents = value_contents_raw (retval);
- data = ctx->data + byte_offset;
+ ldata = ctx->data + byte_offset;
n -= byte_offset;
if (n > TYPE_LENGTH (type))
n = TYPE_LENGTH (type);
- memcpy (contents, data, n);
+ memcpy (contents, ldata, n);
}
break;
+ case DWARF_VALUE_OPTIMIZED_OUT:
+ retval = allocate_value (type);
+ VALUE_LVAL (retval) = not_lval;
+ set_value_optimized_out (retval, 1);
+ 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. */
- case DWARF_VALUE_OPTIMIZED_OUT:
default:
internal_error (__FILE__, __LINE__, _("invalid location type"));
}
{
struct needs_frame_baton *nf_baton = ctx->baton;
- return per_cu_dwarf_call (ctx, die_offset, nf_baton->per_cu,
- ctx->get_frame_pc, ctx->baton);
+ per_cu_dwarf_call (ctx, die_offset, nf_baton->per_cu,
+ ctx->get_frame_pc, ctx->baton);
}
/* Return non-zero iff the location expression at DATA (length SIZE)
error (_("DWARF operator %s cannot be translated to an agent expression"),
name);
else
- error (_("Unknown DWARF operator 0x%02x cannot be to an agent expression"),
+ error (_("Unknown DWARF operator 0x%02x cannot be translated "
+ "to an agent expression"),
op);
}
example, if the expression cannot be compiled, or if the expression
is invalid. */
-static void
-compile_dwarf_to_ax (struct agent_expr *expr, struct axs_value *loc,
- struct gdbarch *arch, unsigned int addr_size,
- const gdb_byte *op_ptr, const gdb_byte *op_end,
- struct dwarf2_per_cu_data *per_cu)
+void
+dwarf2_compile_expr_to_ax (struct agent_expr *expr, struct axs_value *loc,
+ struct gdbarch *arch, unsigned int addr_size,
+ const gdb_byte *op_ptr, const gdb_byte *op_end,
+ struct dwarf2_per_cu_data *per_cu)
{
struct cleanup *cleanups;
int i, *offsets;
&datastart, &datalen);
op_ptr = read_sleb128 (op_ptr, op_end, &offset);
- compile_dwarf_to_ax (expr, loc, arch, addr_size, datastart,
- datastart + datalen, per_cu);
+ dwarf2_compile_expr_to_ax (expr, loc, arch, addr_size, datastart,
+ datastart + datalen, per_cu);
if (offset != 0)
{
case DW_OP_pick:
offset = *op_ptr++;
- unimplemented (op);
+ ax_pick (expr, offset);
break;
case DW_OP_swap:
break;
case DW_OP_over:
- /* We can't directly support DW_OP_over, but GCC emits it as
- part of a sequence to implement signed modulus. As a
- hack, we recognize this sequence. Note that if GCC ever
- generates a branch to the middle of this sequence, then
- we will die somehow. */
- if (op_end - op_ptr >= 4
- && op_ptr[0] == DW_OP_over
- && op_ptr[1] == DW_OP_div
- && op_ptr[2] == DW_OP_mul
- && op_ptr[3] == DW_OP_minus)
- {
- /* Sign extend the operands. */
- ax_ext (expr, addr_size_bits);
- ax_simple (expr, aop_swap);
- ax_ext (expr, addr_size_bits);
- ax_simple (expr, aop_swap);
- ax_simple (expr, aop_rem_signed);
- op_ptr += 4;
- }
- else
- unimplemented (op);
+ ax_pick (expr, 1);
break;
case DW_OP_rot:
- unimplemented (op);
+ ax_simple (expr, aop_rot);
break;
case DW_OP_deref:
break;
case DW_OP_call_frame_cfa:
- unimplemented (op);
+ dwarf2_compile_cfa_to_ax (expr, loc, arch, expr->scope, per_cu);
+ loc->kind = axs_lvalue_memory;
break;
case DW_OP_GNU_push_tls_address:
/* DW_OP_call_ref is currently not supported. */
gdb_assert (block.per_cu == per_cu);
- compile_dwarf_to_ax (expr, loc, arch, addr_size,
- block.data, block.data + block.size,
- per_cu);
+ dwarf2_compile_expr_to_ax (expr, loc, arch, addr_size,
+ block.data, block.data + block.size,
+ per_cu);
}
break;
case DW_OP_breg29:
case DW_OP_breg30:
case DW_OP_breg31:
- data = read_sleb128 (data, end, &ul);
- fprintf_filtered (stream, " %s [$%s]", pulongest (ul),
+ data = read_sleb128 (data, end, &l);
+ fprintf_filtered (stream, " %s [$%s]", plongest (l),
gdbarch_register_name (arch, op - DW_OP_breg0));
break;
case DW_OP_bregx:
- {
- ULONGEST offset;
-
- data = read_uleb128 (data, end, &ul);
- data = read_sleb128 (data, end, &offset);
- fprintf_filtered (stream, " register %s [$%s] offset %s",
- pulongest (ul),
- gdbarch_register_name (arch, (int) ul),
- pulongest (offset));
- }
+ data = read_uleb128 (data, end, &ul);
+ data = read_sleb128 (data, end, &l);
+ fprintf_filtered (stream, " register %s [$%s] offset %s",
+ pulongest (ul),
+ gdbarch_register_name (arch, (int) ul),
+ plongest (l));
break;
case DW_OP_fbreg:
- data = read_sleb128 (data, end, &ul);
- fprintf_filtered (stream, " %s", pulongest (ul));
+ data = read_sleb128 (data, end, &l);
+ fprintf_filtered (stream, " %s", plongest (l));
break;
case DW_OP_xderef_size:
if (dlbaton->data == NULL || dlbaton->size == 0)
value->optimized_out = 1;
else
- compile_dwarf_to_ax (ax, value, gdbarch, addr_size,
- dlbaton->data, dlbaton->data + dlbaton->size,
- dlbaton->per_cu);
+ dwarf2_compile_expr_to_ax (ax, value, gdbarch, addr_size,
+ dlbaton->data, dlbaton->data + dlbaton->size,
+ dlbaton->per_cu);
}
/* The set of location functions used with the DWARF-2 expression
if (data == NULL || size == 0)
value->optimized_out = 1;
else
- compile_dwarf_to_ax (ax, value, gdbarch, addr_size, data, data + size,
- dlbaton->per_cu);
+ dwarf2_compile_expr_to_ax (ax, value, gdbarch, addr_size, data, data + size,
+ dlbaton->per_cu);
}
/* The set of location functions used with the DWARF-2 expression