From patchwork Fri Jul 11 09:21:14 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Keven Boell X-Patchwork-Id: 2028 Received: (qmail 408 invoked by alias); 11 Jul 2014 09:22:09 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Delivered-To: mailing list gdb-patches@sourceware.org Received: (qmail 32729 invoked by uid 89); 11 Jul 2014 09:22:08 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.1 required=5.0 tests=AWL, BAYES_00, RP_MATCHES_RCVD autolearn=ham version=3.3.2 X-HELO: mga14.intel.com Received: from mga14.intel.com (HELO mga14.intel.com) (192.55.52.115) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Fri, 11 Jul 2014 09:22:03 +0000 Received: from fmsmga001.fm.intel.com ([10.253.24.23]) by fmsmga103.fm.intel.com with ESMTP; 11 Jul 2014 02:15:55 -0700 X-ExtLoop1: 1 Received: from irvmail001.ir.intel.com ([163.33.26.43]) by fmsmga001.fm.intel.com with ESMTP; 11 Jul 2014 02:21:38 -0700 Received: from ullecvh004g04.iul.intel.com (ullecvh004g04.iul.intel.com [172.28.50.14]) by irvmail001.ir.intel.com (8.14.3/8.13.6/MailSET/Hub) with ESMTP id s6B9LcLJ020706; Fri, 11 Jul 2014 10:21:38 +0100 Received: from ullecvh004g04.iul.intel.com (ullecvh004g04.iul.intel.com [127.0.0.1]) by ullecvh004g04.iul.intel.com (8.13.8/8.13.8) with ESMTP id s6B9LdYX007001; Fri, 11 Jul 2014 11:21:39 +0200 Received: (from kboell@localhost) by ullecvh004g04.iul.intel.com (8.13.8/8.13.8/Submit) id s6B9LcOX007000; Fri, 11 Jul 2014 11:21:38 +0200 From: Keven Boell To: gdb-patches@sourceware.org Cc: keven.boell@intel.com, sanimir.agovic@intel.com Subject: [V2 02/23] dwarf: add DW_AT_data_location support Date: Fri, 11 Jul 2014 11:21:14 +0200 Message-Id: <1405070495-6948-3-git-send-email-keven.boell@intel.com> In-Reply-To: <1405070495-6948-1-git-send-email-keven.boell@intel.com> References: <1405070495-6948-1-git-send-email-keven.boell@intel.com> An object might have a descriptor proceeding the actual value. To point the debugger to the actually value of an object DW_AT_data_location is used for. For example the compile may emit for this entity: 1| int foo[N]; the following descriptor: struct array { size_t size; void* data; // DW_AT_data_location describes this location } This allows GDB to print the actual data of an type. E.g. for the related dwarf output of a dynamic array using DW_AT_data_location: <1>: Abbrev Number: 8 (DW_TAG_array_type) DW_AT_data_location: 2 byte block: 97 6 (DW_OP_push_object_address; DW_OP_deref) 2014-05-28 Sanimir Agovic Keven Boell * dwarf2read.c (set_die_type): Parse and save DW_AT_data_location attribute. * gdbtypes.c (is_dynamic_type): Consider a type being dynamic if the data location has not yet been resolved. (resolve_dynamic_type): Evaluate data location baton if present and save its value. * gdbtypes.h : Add data_location. (TYPE_DATA_LOCATION): New macro. (TYPE_DATA_LOCATION_ADDR): New macro. (TYPE_DATA_LOCATION_IS_ADDRESS): New macro. * value.c: Include dwarf2loc.h. (value_fetch_lazy): Use data location addres to read value from memory. (coerce_ref): Construct new value from data location. Change-Id: Ic633fa125efdb5e438204e4f80bb3a1c97758b12 Signed-off-by: Keven Boell --- gdb/dwarf2read.c | 11 +++++++++++ gdb/gdbtypes.c | 33 ++++++++++++++++++++++++++++++--- gdb/gdbtypes.h | 15 +++++++++++++++ gdb/value.c | 8 +++++++- 4 files changed, 63 insertions(+), 4 deletions(-) diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c index 276d2f1..20886b0 100644 --- a/gdb/dwarf2read.c +++ b/gdb/dwarf2read.c @@ -21673,6 +21673,8 @@ set_die_type (struct die_info *die, struct type *type, struct dwarf2_cu *cu) { struct dwarf2_per_cu_offset_and_type **slot, ofs; struct objfile *objfile = cu->objfile; + struct attribute *attr; + struct dynamic_prop prop; /* For Ada types, make sure that the gnat-specific data is always initialized (if not already set). There are a few types where @@ -21687,6 +21689,15 @@ set_die_type (struct die_info *die, struct type *type, struct dwarf2_cu *cu) && !HAVE_GNAT_AUX_INFO (type)) INIT_GNAT_SPECIFIC (type); + /* Read DW_AT_data_location and set in type. */ + attr = dwarf2_attr (die, DW_AT_data_location, cu); + if (attr_to_dynamic_prop (attr, die, cu, &prop)) + { + TYPE_DATA_LOCATION (type) + = obstack_alloc (&objfile->objfile_obstack, sizeof (prop)); + *TYPE_DATA_LOCATION (type) = prop; + } + if (dwarf2_per_objfile->die_type_hash == NULL) { dwarf2_per_objfile->die_type_hash = diff --git a/gdb/gdbtypes.c b/gdb/gdbtypes.c index 08e5884..f4da142 100644 --- a/gdb/gdbtypes.c +++ b/gdb/gdbtypes.c @@ -1630,11 +1630,19 @@ is_dynamic_type (struct type *type) { gdb_assert (TYPE_NFIELDS (type) == 1); - /* The array is dynamic if either the bounds are dynamic, - or the elements it contains have a dynamic contents. */ + /* The array is dynamic if either + - the bounds are dynamic, + - the elements it contains have a dynamic contents + - a data_locaton attribute was found. */ if (is_dynamic_type (TYPE_INDEX_TYPE (type))) return 1; - return is_dynamic_type (TYPE_TARGET_TYPE (type)); + else if (TYPE_DATA_LOCATION (type) != NULL + && (TYPE_DATA_LOCATION_KIND (type) == PROP_LOCEXPR + || TYPE_DATA_LOCATION_KIND (type) == PROP_LOCLIST)) + return 1; + else + return is_dynamic_type (TYPE_TARGET_TYPE (type)); + break; } case TYPE_CODE_STRUCT: @@ -1830,6 +1838,8 @@ resolve_dynamic_type (struct type *type, CORE_ADDR addr) { struct type *real_type = check_typedef (type); struct type *resolved_type = type; + const struct dynamic_prop *prop; + CORE_ADDR value; if (!is_dynamic_type (real_type)) return type; @@ -1869,6 +1879,16 @@ resolve_dynamic_type (struct type *type, CORE_ADDR addr) break; } + /* Resolve data_location attribute. */ + prop = TYPE_DATA_LOCATION (resolved_type); + if (dwarf2_evaluate_property (prop, addr, &value)) + { + TYPE_DATA_LOCATION_ADDR (resolved_type) = value; + TYPE_DATA_LOCATION_KIND (resolved_type) = PROP_CONST; + } + else + TYPE_DATA_LOCATION (resolved_type) = NULL; + return resolved_type; } @@ -4078,6 +4098,13 @@ copy_type_recursive (struct objfile *objfile, *TYPE_RANGE_DATA (new_type) = *TYPE_RANGE_DATA (type); } + /* Copy the data location information. */ + if (TYPE_DATA_LOCATION (type) != NULL) + { + TYPE_DATA_LOCATION (new_type) = xmalloc (sizeof (struct dynamic_prop)); + *TYPE_DATA_LOCATION (new_type) = *TYPE_DATA_LOCATION (type); + } + /* Copy pointers to other types. */ if (TYPE_TARGET_TYPE (type)) TYPE_TARGET_TYPE (new_type) = diff --git a/gdb/gdbtypes.h b/gdb/gdbtypes.h index bb6352d..17b9fe0 100644 --- a/gdb/gdbtypes.h +++ b/gdb/gdbtypes.h @@ -725,6 +725,11 @@ struct main_type struct func_type *func_stuff; } type_specific; + + /* * Contains a location description value for the current type. Evaluating + this field yields to the location of the data for an object. */ + + struct dynamic_prop *data_location; }; /* * A ``struct type'' describes a particular instance of a type, with @@ -1204,6 +1209,16 @@ extern void allocate_gnat_aux_type (struct type *); #define TYPE_LOW_BOUND_KIND(range_type) \ TYPE_RANGE_DATA(range_type)->low.kind +/* Attribute accessors for the type data location. */ +#define TYPE_DATA_LOCATION(thistype) \ + TYPE_MAIN_TYPE(thistype)->data_location +#define TYPE_DATA_LOCATION_BATON(thistype) \ + TYPE_DATA_LOCATION (thistype)->data.baton +#define TYPE_DATA_LOCATION_ADDR(thistype) \ + TYPE_DATA_LOCATION (thistype)->data.const_val +#define TYPE_DATA_LOCATION_KIND(thistype) \ + TYPE_DATA_LOCATION (thistype)->kind + /* Moto-specific stuff for FORTRAN arrays. */ #define TYPE_ARRAY_UPPER_BOUND_IS_UNDEFINED(arraytype) \ diff --git a/gdb/value.c b/gdb/value.c index 557056f..3c73683 100644 --- a/gdb/value.c +++ b/gdb/value.c @@ -3699,8 +3699,14 @@ value_fetch_lazy (struct value *val) } else if (VALUE_LVAL (val) == lval_memory) { - CORE_ADDR addr = value_address (val); struct type *type = check_typedef (value_enclosing_type (val)); + CORE_ADDR addr; + + if (TYPE_DATA_LOCATION (type) != NULL + && TYPE_DATA_LOCATION_KIND (type) == PROP_CONST) + addr = TYPE_DATA_LOCATION_ADDR (type); + else + addr = value_address (val); if (TYPE_LENGTH (type)) read_value_memory (val, 0, value_stack (val),