aboutsummaryrefslogtreecommitdiff
path: root/gdb/dwarf2loc.c
diff options
context:
space:
mode:
authorSanimir Agovic <sanimir.agovic@intel.com>2013-10-09 15:28:22 +0100
committerSanimir Agovic <sanimir.agovic@intel.com>2014-04-11 13:43:48 +0100
commit37c1ab67a35025d37d42c449deab5f254f9f59da (patch)
tree58b22b4d781f80685e330c47d41571991a082fa2 /gdb/dwarf2loc.c
parent729efb13174d6522fba4aa7ab273e7f25a253c47 (diff)
downloadgdb-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.c119
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. */