diff options
author | Sanimir Agovic <sanimir.agovic@intel.com> | 2013-10-09 15:28:22 +0100 |
---|---|---|
committer | Sanimir Agovic <sanimir.agovic@intel.com> | 2014-04-11 13:43:48 +0100 |
commit | 37c1ab67a35025d37d42c449deab5f254f9f59da (patch) | |
tree | 58b22b4d781f80685e330c47d41571991a082fa2 /gdb/dwarf2loc.c | |
parent | 729efb13174d6522fba4aa7ab273e7f25a253c47 (diff) | |
download | gdb-37c1ab67a35025d37d42c449deab5f254f9f59da.zip gdb-37c1ab67a35025d37d42c449deab5f254f9f59da.tar.gz gdb-37c1ab67a35025d37d42c449deab5f254f9f59da.tar.bz2 |
type: add c99 variable length array support
The dwarf standard allow certain attributes to be expressed as dwarf
expressions rather than constants. For instance upper-/lowerbound attributes.
In case of a c99 variable length array the upperbound is a dynamic attribute.
With this change c99 vla behave the same as with static arrays.
1| void foo (size_t n) {
2| int ary[n];
3| memset(ary, 0, sizeof(ary));
4| }
(gdb) print ary
$1 = {0 <repeats 42 times>}
* dwarf2loc.c (dwarf2_locexpr_baton_eval): New function.
(dwarf2_evaluate_property): New function.
* dwarf2loc.h (dwarf2_evaluate_property): New function prototype.
* dwarf2read.c (attr_to_dynamic_prop): New function.
(read_subrange_type): Use attr_to_dynamic_prop to read high bound
attribute.
* gdbtypes.c: Include dwarf2loc.h.
(is_dynamic_type): New function.
(resolve_dynamic_type): New function.
(resolve_dynamic_bounds): New function.
(get_type_length): New function.
(check_typedef): Use get_type_length to compute type length.
* gdbtypes.h (TYPE_HIGH_BOUND_KIND): New macro.
(TYPE_LOW_BOUND_KIND): New macro.
(is_dynamic_type): New function prototype.
* value.c (value_from_contents_and_address): Call resolve_dynamic_type
to resolve dynamic properties of the type. Update comment.
* valops.c (get_value_at, value_at, value_at_lazy): Update comment.
Diffstat (limited to 'gdb/dwarf2loc.c')
-rw-r--r-- | gdb/dwarf2loc.c | 119 |
1 files changed, 119 insertions, 0 deletions
diff --git a/gdb/dwarf2loc.c b/gdb/dwarf2loc.c index e91b764..addae13 100644 --- a/gdb/dwarf2loc.c +++ b/gdb/dwarf2loc.c @@ -2432,6 +2432,125 @@ dwarf2_evaluate_loc_desc (struct type *type, struct frame_info *frame, return dwarf2_evaluate_loc_desc_full (type, frame, data, size, per_cu, 0); } +/* Evaluates a dwarf expression and stores the result in VAL, expecting + that the dwarf expression only produces a single CORE_ADDR. ADDR is a + context (location of a variable) and might be needed to evaluate the + location expression. + Returns 1 on success, 0 otherwise. */ + +static int +dwarf2_locexpr_baton_eval (const struct dwarf2_locexpr_baton *dlbaton, + CORE_ADDR addr, CORE_ADDR *valp) +{ + struct dwarf_expr_context *ctx; + struct dwarf_expr_baton baton; + struct objfile *objfile; + struct cleanup *cleanup; + + if (dlbaton == NULL || dlbaton->size == 0) + return 0; + + ctx = new_dwarf_expr_context (); + cleanup = make_cleanup_free_dwarf_expr_context (ctx); + + baton.frame = get_selected_frame (NULL); + baton.per_cu = dlbaton->per_cu; + + objfile = dwarf2_per_cu_objfile (dlbaton->per_cu); + + ctx->gdbarch = get_objfile_arch (objfile); + ctx->addr_size = dwarf2_per_cu_addr_size (dlbaton->per_cu); + ctx->ref_addr_size = dwarf2_per_cu_ref_addr_size (dlbaton->per_cu); + ctx->offset = dwarf2_per_cu_text_offset (dlbaton->per_cu); + ctx->funcs = &dwarf_expr_ctx_funcs; + ctx->baton = &baton; + + dwarf_expr_eval (ctx, dlbaton->data, dlbaton->size); + + switch (ctx->location) + { + case DWARF_VALUE_REGISTER: + case DWARF_VALUE_MEMORY: + case DWARF_VALUE_STACK: + *valp = dwarf_expr_fetch_address (ctx, 0); + if (ctx->location == DWARF_VALUE_REGISTER) + *valp = dwarf_expr_read_addr_from_reg (&baton, *valp); + do_cleanups (cleanup); + return 1; + case DWARF_VALUE_LITERAL: + *valp = extract_signed_integer (ctx->data, ctx->len, + gdbarch_byte_order (ctx->gdbarch)); + do_cleanups (cleanup); + return 1; + /* Unsupported dwarf values. */ + case DWARF_VALUE_OPTIMIZED_OUT: + case DWARF_VALUE_IMPLICIT_POINTER: + break; + } + + do_cleanups (cleanup); + return 0; +} + +/* See dwarf2loc.h. */ + +int +dwarf2_evaluate_property (const struct dynamic_prop *prop, CORE_ADDR address, + CORE_ADDR *value) +{ + if (prop == NULL) + return 0; + + switch (prop->kind) + { + case PROP_LOCEXPR: + { + const struct dwarf2_property_baton *baton = prop->data.baton; + + if (dwarf2_locexpr_baton_eval (&baton->locexpr, address, value)) + { + if (baton->referenced_type) + { + struct value *val = value_at (baton->referenced_type, *value); + + *value = value_as_address (val); + } + return 1; + } + } + break; + + case PROP_LOCLIST: + { + struct dwarf2_property_baton *baton = prop->data.baton; + struct frame_info *frame = get_selected_frame (NULL); + CORE_ADDR pc = get_frame_address_in_block (frame); + const gdb_byte *data; + struct value *val; + size_t size; + + data = dwarf2_find_location_expression (&baton->loclist, &size, pc); + if (data != NULL) + { + val = dwarf2_evaluate_loc_desc (baton->referenced_type, frame, data, + size, baton->loclist.per_cu); + if (!value_optimized_out (val)) + { + *value = value_as_address (val); + return 1; + } + } + } + break; + + case PROP_CONST: + *value = prop->data.const_val; + return 1; + } + + return 0; +} + /* Helper functions and baton for dwarf2_loc_desc_needs_frame. */ |