Add support for DW_OP_push_object_address.

gdb/ChangeLog:

        * dwarf2expr.h (struct dwarf_expr_context_funcs): Uncomment
        field "get_object_address".
        * dwarf2expr.c (execute_stack_op): Add handling for
        DW_OP_push_object_address.
        * dwarf2loc.h (dwarf2_evaluate_property): Add "address" field.
        * dwarf2loc.c (struct dwarf_expr_baton): Add field "obj_address".
        (dwarf_expr_push_dwarf_reg_entry_value): Set baton_local.obj_address.
        (dwarf_expr_get_obj_addr): New function.
        (dwarf_expr_ctx_funcs): Add get_object_address field.
        (dwarf2_evaluate_loc_desc_full): Set baton.obj_address.
        (dwarf2_locexpr_baton_eval): Add parameter "addr".  Use it.
        (dwarf2_evaluate_property): Add parameter "address".  Use it.
        (needs_get_obj_addr): New function.
        (needs_frame_ctx_funcs): Add get_object_address field.
        (dwarf2_compile_expr_to_ax): Add DW_OP_push_object_address handling.
        * gdbtypes.c (resolve_dynamic_range): Add "addr" field.  Use it.
        (resolve_dynamic_array): Likewise.
This commit is contained in:
Joel Brobecker 2014-08-11 16:36:04 -07:00
parent 84754697d2
commit 08412b0722
6 changed files with 79 additions and 18 deletions

View File

@ -1,3 +1,24 @@
2014-08-18 Keven Boell <keven.boell@intel.com>
Joel Brobecker <brobecker@adacore.com>
* dwarf2expr.h (struct dwarf_expr_context_funcs): Uncomment
field "get_object_address".
* dwarf2expr.c (execute_stack_op): Add handling for
DW_OP_push_object_address.
* dwarf2loc.h (dwarf2_evaluate_property): Add "address" field.
* dwarf2loc.c (struct dwarf_expr_baton): Add field "obj_address".
(dwarf_expr_push_dwarf_reg_entry_value): Set baton_local.obj_address.
(dwarf_expr_get_obj_addr): New function.
(dwarf_expr_ctx_funcs): Add get_object_address field.
(dwarf2_evaluate_loc_desc_full): Set baton.obj_address.
(dwarf2_locexpr_baton_eval): Add parameter "addr". Use it.
(dwarf2_evaluate_property): Add parameter "address". Use it.
(needs_get_obj_addr): New function.
(needs_frame_ctx_funcs): Add get_object_address field.
(dwarf2_compile_expr_to_ax): Add DW_OP_push_object_address handling.
* gdbtypes.c (resolve_dynamic_range): Add "addr" field. Use it.
(resolve_dynamic_array): Likewise.
2014-08-18 Joel Brobecker <brobecker@adacore.com> 2014-08-18 Joel Brobecker <brobecker@adacore.com>
* ada-lang.c (ada_evaluate_subexp) <OP_VAR_VALUE>: * ada-lang.c (ada_evaluate_subexp) <OP_VAR_VALUE>:

View File

@ -1477,6 +1477,12 @@ execute_stack_op (struct dwarf_expr_context *ctx,
} }
break; 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: default:
error (_("Unhandled dwarf expression opcode 0x%x"), op); error (_("Unhandled dwarf expression opcode 0x%x"), op);
} }

View File

@ -84,12 +84,8 @@ struct dwarf_expr_context_funcs
This can throw an exception if the index is out of range. */ This can throw an exception if the index is out of range. */
CORE_ADDR (*get_addr_index) (void *baton, unsigned int index); CORE_ADDR (*get_addr_index) (void *baton, unsigned int index);
#if 0
/* Not yet implemented. */
/* Return the `object address' for DW_OP_push_object_address. */ /* Return the `object address' for DW_OP_push_object_address. */
CORE_ADDR (*get_object_address) (void *baton); CORE_ADDR (*get_object_address) (void *baton);
#endif
}; };
/* The location of a value. */ /* The location of a value. */

View File

@ -303,6 +303,7 @@ struct dwarf_expr_baton
{ {
struct frame_info *frame; struct frame_info *frame;
struct dwarf2_per_cu_data *per_cu; struct dwarf2_per_cu_data *per_cu;
CORE_ADDR obj_address;
}; };
/* Helper functions for dwarf2_evaluate_loc_desc. */ /* Helper functions for dwarf2_evaluate_loc_desc. */
@ -1206,6 +1207,7 @@ dwarf_expr_push_dwarf_reg_entry_value (struct dwarf_expr_context *ctx,
baton_local.frame = caller_frame; baton_local.frame = caller_frame;
baton_local.per_cu = caller_per_cu; baton_local.per_cu = caller_per_cu;
baton_local.obj_address = 0;
saved_ctx.gdbarch = ctx->gdbarch; saved_ctx.gdbarch = ctx->gdbarch;
saved_ctx.addr_size = ctx->addr_size; saved_ctx.addr_size = ctx->addr_size;
@ -1235,6 +1237,22 @@ dwarf_expr_get_addr_index (void *baton, unsigned int index)
return dwarf2_read_addr_index (debaton->per_cu, index); return dwarf2_read_addr_index (debaton->per_cu, index);
} }
/* Callback function for get_object_address. Return the address of the VLA
object. */
static CORE_ADDR
dwarf_expr_get_obj_addr (void *baton)
{
struct dwarf_expr_baton *debaton = baton;
gdb_assert (debaton != NULL);
if (debaton->obj_address == 0)
error (_("Location address is not set."));
return debaton->obj_address;
}
/* VALUE must be of type lval_computed with entry_data_value_funcs. Perform /* 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 the indirect method on it, that is use its stored target value, the sole
purpose of entry_data_value_funcs.. */ purpose of entry_data_value_funcs.. */
@ -2190,7 +2208,8 @@ static const struct dwarf_expr_context_funcs dwarf_expr_ctx_funcs =
dwarf_expr_dwarf_call, dwarf_expr_dwarf_call,
dwarf_expr_get_base_type, dwarf_expr_get_base_type,
dwarf_expr_push_dwarf_reg_entry_value, dwarf_expr_push_dwarf_reg_entry_value,
dwarf_expr_get_addr_index dwarf_expr_get_addr_index,
dwarf_expr_get_obj_addr
}; };
/* Evaluate a location description, starting at DATA and with length /* Evaluate a location description, starting at DATA and with length
@ -2219,6 +2238,7 @@ dwarf2_evaluate_loc_desc_full (struct type *type, struct frame_info *frame,
baton.frame = frame; baton.frame = frame;
baton.per_cu = per_cu; baton.per_cu = per_cu;
baton.obj_address = 0;
ctx = new_dwarf_expr_context (); ctx = new_dwarf_expr_context ();
old_chain = make_cleanup_free_dwarf_expr_context (ctx); old_chain = make_cleanup_free_dwarf_expr_context (ctx);
@ -2424,6 +2444,7 @@ dwarf2_evaluate_loc_desc (struct type *type, struct frame_info *frame,
static int static int
dwarf2_locexpr_baton_eval (const struct dwarf2_locexpr_baton *dlbaton, dwarf2_locexpr_baton_eval (const struct dwarf2_locexpr_baton *dlbaton,
CORE_ADDR addr,
CORE_ADDR *valp) CORE_ADDR *valp)
{ {
struct dwarf_expr_context *ctx; struct dwarf_expr_context *ctx;
@ -2439,6 +2460,7 @@ dwarf2_locexpr_baton_eval (const struct dwarf2_locexpr_baton *dlbaton,
baton.frame = get_selected_frame (NULL); baton.frame = get_selected_frame (NULL);
baton.per_cu = dlbaton->per_cu; baton.per_cu = dlbaton->per_cu;
baton.obj_address = addr;
objfile = dwarf2_per_cu_objfile (dlbaton->per_cu); objfile = dwarf2_per_cu_objfile (dlbaton->per_cu);
@ -2479,7 +2501,8 @@ dwarf2_locexpr_baton_eval (const struct dwarf2_locexpr_baton *dlbaton,
/* See dwarf2loc.h. */ /* See dwarf2loc.h. */
int int
dwarf2_evaluate_property (const struct dynamic_prop *prop, CORE_ADDR *value) dwarf2_evaluate_property (const struct dynamic_prop *prop,
CORE_ADDR address, CORE_ADDR *value)
{ {
if (prop == NULL) if (prop == NULL)
return 0; return 0;
@ -2490,7 +2513,7 @@ dwarf2_evaluate_property (const struct dynamic_prop *prop, CORE_ADDR *value)
{ {
const struct dwarf2_property_baton *baton = prop->data.baton; const struct dwarf2_property_baton *baton = prop->data.baton;
if (dwarf2_locexpr_baton_eval (&baton->locexpr, value)) if (dwarf2_locexpr_baton_eval (&baton->locexpr, address, value))
{ {
if (baton->referenced_type) if (baton->referenced_type)
{ {
@ -2641,6 +2664,15 @@ needs_get_addr_index (void *baton, unsigned int index)
return 1; return 1;
} }
/* DW_OP_push_object_address has a frame already passed through. */
static CORE_ADDR
needs_get_obj_addr (void *baton)
{
/* Nothing to do. */
return 1;
}
/* Virtual method table for dwarf2_loc_desc_needs_frame below. */ /* Virtual method table for dwarf2_loc_desc_needs_frame below. */
static const struct dwarf_expr_context_funcs needs_frame_ctx_funcs = static const struct dwarf_expr_context_funcs needs_frame_ctx_funcs =
@ -2655,7 +2687,8 @@ static const struct dwarf_expr_context_funcs needs_frame_ctx_funcs =
needs_frame_dwarf_call, needs_frame_dwarf_call,
NULL, /* get_base_type */ NULL, /* get_base_type */
needs_dwarf_reg_entry_value, needs_dwarf_reg_entry_value,
needs_get_addr_index needs_get_addr_index,
needs_get_obj_addr
}; };
/* Return non-zero iff the location expression at DATA (length SIZE) /* Return non-zero iff the location expression at DATA (length SIZE)
@ -3304,6 +3337,10 @@ dwarf2_compile_expr_to_ax (struct agent_expr *expr, struct axs_value *loc,
unimplemented (op); unimplemented (op);
break; break;
case DW_OP_push_object_address:
unimplemented (op);
break;
case DW_OP_skip: case DW_OP_skip:
offset = extract_signed_integer (op_ptr, 2, byte_order); offset = extract_signed_integer (op_ptr, 2, byte_order);
op_ptr += 2; op_ptr += 2;

View File

@ -96,6 +96,7 @@ struct value *dwarf2_evaluate_loc_desc (struct type *type,
into VALUE, otherwise returns 0. */ into VALUE, otherwise returns 0. */
int dwarf2_evaluate_property (const struct dynamic_prop *prop, int dwarf2_evaluate_property (const struct dynamic_prop *prop,
CORE_ADDR address,
CORE_ADDR *value); CORE_ADDR *value);
CORE_ADDR dwarf2_read_addr_index (struct dwarf2_per_cu_data *per_cu, CORE_ADDR dwarf2_read_addr_index (struct dwarf2_per_cu_data *per_cu,

View File

@ -1664,11 +1664,11 @@ static struct type *resolve_dynamic_type_internal (struct type *type,
CORE_ADDR addr, CORE_ADDR addr,
int top_level); int top_level);
/* Given a dynamic range type (dyn_range_type), return a static version /* Given a dynamic range type (dyn_range_type) and address,
of that type. */ return a static version of that type. */
static struct type * static struct type *
resolve_dynamic_range (struct type *dyn_range_type) resolve_dynamic_range (struct type *dyn_range_type, CORE_ADDR addr)
{ {
CORE_ADDR value; CORE_ADDR value;
struct type *static_range_type; struct type *static_range_type;
@ -1679,7 +1679,7 @@ resolve_dynamic_range (struct type *dyn_range_type)
gdb_assert (TYPE_CODE (dyn_range_type) == TYPE_CODE_RANGE); gdb_assert (TYPE_CODE (dyn_range_type) == TYPE_CODE_RANGE);
prop = &TYPE_RANGE_DATA (dyn_range_type)->low; prop = &TYPE_RANGE_DATA (dyn_range_type)->low;
if (dwarf2_evaluate_property (prop, &value)) if (dwarf2_evaluate_property (prop, addr, &value))
{ {
low_bound.kind = PROP_CONST; low_bound.kind = PROP_CONST;
low_bound.data.const_val = value; low_bound.data.const_val = value;
@ -1691,7 +1691,7 @@ resolve_dynamic_range (struct type *dyn_range_type)
} }
prop = &TYPE_RANGE_DATA (dyn_range_type)->high; prop = &TYPE_RANGE_DATA (dyn_range_type)->high;
if (dwarf2_evaluate_property (prop, &value)) if (dwarf2_evaluate_property (prop, addr, &value))
{ {
high_bound.kind = PROP_CONST; high_bound.kind = PROP_CONST;
high_bound.data.const_val = value; high_bound.data.const_val = value;
@ -1718,7 +1718,7 @@ resolve_dynamic_range (struct type *dyn_range_type)
of the associated array. */ of the associated array. */
static struct type * static struct type *
resolve_dynamic_array (struct type *type) resolve_dynamic_array (struct type *type, CORE_ADDR addr)
{ {
CORE_ADDR value; CORE_ADDR value;
struct type *elt_type; struct type *elt_type;
@ -1729,12 +1729,12 @@ resolve_dynamic_array (struct type *type)
elt_type = type; elt_type = type;
range_type = check_typedef (TYPE_INDEX_TYPE (elt_type)); range_type = check_typedef (TYPE_INDEX_TYPE (elt_type));
range_type = resolve_dynamic_range (range_type); range_type = resolve_dynamic_range (range_type, addr);
ary_dim = check_typedef (TYPE_TARGET_TYPE (elt_type)); ary_dim = check_typedef (TYPE_TARGET_TYPE (elt_type));
if (ary_dim != NULL && TYPE_CODE (ary_dim) == TYPE_CODE_ARRAY) if (ary_dim != NULL && TYPE_CODE (ary_dim) == TYPE_CODE_ARRAY)
elt_type = resolve_dynamic_array (TYPE_TARGET_TYPE (type)); elt_type = resolve_dynamic_array (TYPE_TARGET_TYPE (type), addr);
else else
elt_type = TYPE_TARGET_TYPE (type); elt_type = TYPE_TARGET_TYPE (type);
@ -1877,11 +1877,11 @@ resolve_dynamic_type_internal (struct type *type, CORE_ADDR addr,
} }
case TYPE_CODE_ARRAY: case TYPE_CODE_ARRAY:
resolved_type = resolve_dynamic_array (type); resolved_type = resolve_dynamic_array (type, addr);
break; break;
case TYPE_CODE_RANGE: case TYPE_CODE_RANGE:
resolved_type = resolve_dynamic_range (type); resolved_type = resolve_dynamic_range (type, addr);
break; break;
case TYPE_CODE_UNION: case TYPE_CODE_UNION: