retval->num_pieces = 0;
retval->pieces = 0;
retval->max_recursion_depth = 0x100;
- retval->mark = value_mark ();
return retval;
}
void
free_dwarf_expr_context (struct dwarf_expr_context *ctx)
{
- value_free_to_mark (ctx->mark);
xfree (ctx->stack);
xfree (ctx->pieces);
xfree (ctx);
}
}
+/* 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. */
CORE_ADDR
error (_("read_uleb128: Corrupted DWARF expression."));
byte = *buf++;
- result |= (byte & 0x7f) << shift;
+ result |= ((ULONGEST) (byte & 0x7f)) << shift;
if ((byte & 0x80) == 0)
break;
shift += 7;
error (_("read_sleb128: Corrupted DWARF expression."));
byte = *buf++;
- result |= (byte & 0x7f) << shift;
+ result |= ((ULONGEST) (byte & 0x7f)) << shift;
shift += 7;
if ((byte & 0x80) == 0)
break;
}
if (shift < (sizeof (*r) * 8) && (byte & 0x40) != 0)
- result |= -(1 << shift);
+ result |= -(((LONGEST) 1) << shift);
*r = result;
return buf;
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);
}
{
struct type *result;
- if (ctx->get_base_type)
+ if (ctx->funcs->get_base_type)
{
- result = ctx->get_base_type (ctx, die);
+ 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"));
}
LONGEST 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)
{
case DW_OP_lit0:
&& *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;
case DW_OP_breg31:
{
op_ptr = read_sleb128 (op_ptr, op_end, &offset);
- result = (ctx->read_reg) (ctx->baton, op - DW_OP_breg0);
+ result = (ctx->funcs->read_reg) (ctx->baton, op - DW_OP_breg0);
result += offset;
result_val = value_from_ulongest (address_type, result);
}
{
op_ptr = read_uleb128 (op_ptr, op_end, ®);
op_ptr = read_sleb128 (op_ptr, op_end, &offset);
- result = (ctx->read_reg) (ctx->baton, reg);
+ result = (ctx->funcs->read_reg) (ctx->baton, reg);
result += offset;
result_val = value_from_ulongest (address_type, result);
}
/* 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,
- value_as_long (dwarf_expr_fetch (ctx, 0)));
+ result = (ctx->funcs->read_reg) (ctx->baton,
+ value_as_long (dwarf_expr_fetch (ctx, 0)));
else
error (_("Not implemented: computing frame "
"base using explicit value operator"));
else
type = address_type;
- (ctx->read_mem) (ctx->baton, buf, addr, addr_size);
+ (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 = 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;
}
case DW_OP_shr:
dwarf_require_integral (value_type (first));
dwarf_require_integral (value_type (second));
- if (value_type (first) == address_type)
+ if (!TYPE_UNSIGNED (value_type (first)))
{
struct type *utype
= get_unsigned_type (ctx->gdbarch, value_type (first));
case DW_OP_shra:
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:
dwarf_require_integral (value_type (first));
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;
returned. */
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_call2:
result = extract_unsigned_integer (op_ptr, 2, byte_order);
op_ptr += 2;
- ctx->dwarf_call (ctx, result);
+ ctx->funcs->dwarf_call (ctx, result);
goto no_push;
case DW_OP_call4:
result = extract_unsigned_integer (op_ptr, 4, byte_order);
op_ptr += 4;
- ctx->dwarf_call (ctx, result);
+ ctx->funcs->dwarf_call (ctx, result);
goto no_push;
case DW_OP_GNU_entry_value:
op_ptr = read_uleb128 (op_ptr, op_end, &type_die);
type = dwarf_get_base_type (ctx, type_die, 0);
- result = (ctx->read_reg) (ctx->baton, reg);
- result_val = value_from_ulongest (type, result);
+ 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));
}
break;
op_ptr = read_uleb128 (op_ptr, op_end, &type_die);
- type = dwarf_get_base_type (ctx, type_die, 0);
+ if (type_die == 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);