From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 16053 invoked by alias); 19 Oct 2010 11:24:17 -0000 Received: (qmail 16044 invoked by uid 22791); 19 Oct 2010 11:24:14 -0000 X-SWARE-Spam-Status: No, hits=-1.5 required=5.0 tests=AWL,BAYES_00,TW_BJ,TW_CP,TW_VP,T_RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from mtagate2.uk.ibm.com (HELO mtagate2.uk.ibm.com) (194.196.100.162) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Tue, 19 Oct 2010 11:24:07 +0000 Received: from d06nrmr1806.portsmouth.uk.ibm.com (d06nrmr1806.portsmouth.uk.ibm.com [9.149.39.193]) by mtagate2.uk.ibm.com (8.13.1/8.13.1) with ESMTP id o9JBO4mN019734 for ; Tue, 19 Oct 2010 11:24:04 GMT Received: from d06av01.portsmouth.uk.ibm.com (d06av01.portsmouth.uk.ibm.com [9.149.37.212]) by d06nrmr1806.portsmouth.uk.ibm.com (8.13.8/8.13.8/NCO v10.0) with ESMTP id o9JBO5aa3875036 for ; Tue, 19 Oct 2010 12:24:05 +0100 Received: from d06av01.portsmouth.uk.ibm.com (loopback [127.0.0.1]) by d06av01.portsmouth.uk.ibm.com (8.12.11.20060308/8.13.3) with ESMTP id o9JBO4o9013723 for ; Tue, 19 Oct 2010 12:24:04 +0100 Received: from leonard.localnet (dyn-9-152-224-33.boeblingen.de.ibm.com [9.152.224.33]) by d06av01.portsmouth.uk.ibm.com (8.12.11.20060308/8.12.11) with ESMTP id o9JBNvoi013353 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO) for ; Tue, 19 Oct 2010 12:24:04 +0100 From: Ken Werner To: gdb-patches@sourceware.org Subject: [patch] DW_AT_byte_size for array type entries Date: Tue, 19 Oct 2010 11:24:00 -0000 User-Agent: KMail/1.13.5 (Linux/2.6.35-22-generic-pae; KDE/4.5.1; i686; ; ) MIME-Version: 1.0 Content-Type: Multipart/Mixed; boundary="Boundary-00=_N/XvMeK8j1EQ+39" Message-Id: <201010191323.57251.ken@linux.vnet.ibm.com> X-IsSubscribed: yes Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org X-SW-Source: 2010-10/txt/msg00292.txt.bz2 --Boundary-00=_N/XvMeK8j1EQ+39 Content-Type: Text/Plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Content-length: 1108 Hi, Section 5.4 of the DWARF standard allows to specify extra padding bytes for array type entries by using the DW_AT_byte_size attribute. This is used for example to specify the types for OpenCL 3-component vectors whose size and alignment are those of 4-component vectors. Currently the GDB does not understand this mechanism and the attached patch attempts to fix this. It extends the DWARF reader (dwarf2read.c:read_array_type) to respect the DW_AT_byte_size attribute and set the length of the array accordingly. This breaks the code that assumes that the number of elements of an array is simply the length of the array type divided by the length of the element type. Therefore the patch queries the number of array elements using the get_array_bounds function that has been enhanced to only return the bounds if they are defined (TYPE_ARRAY_[LOWER|UPPER]_BOUND_IS_UNDEFINED). In order to prevent the inclusion of the valprint.h header the get_array_bounds function has been moved from valprint.[c|h] to gdbtypes.[c|h]. Tested on i686-*-linux-gnu with no regressions. Regards Ken Werner --Boundary-00=_N/XvMeK8j1EQ+39 Content-Type: text/x-patch; charset="UTF-8"; name="DW_AT_byte_size.patch" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="DW_AT_byte_size.patch" Content-length: 13890 ChangeLog: 2010-10-19 Ken Werner * dwarf2read.c (read_array_type): Read the DW_AT_byte_size from the DIE and set the length of the type. * gdbtypes.h (get_array_bounds): Move here from valprint.h. * gdbtypes.c (get_array_bounds): Move here from valprint.c and return 0 if the corresponding bounds of the type are undefined. * valprint.h (get_array_bounds): Move declaration to gdbtypes.h. * valprint.c (get_array_bounds): Move implementation to gdbtypes.c. (val_print_array_elements): Use get_array_bounds to compute the number of array elements instead of dividing the length of the array by the length of the element types. * valarith.c (vector_binop): Likewise. * valops.c (value_cast): Likewise. * c-valprint.c (c_val_print): Likewise. * c-typeprint.c (c_type_print_varspec_suffix): Likewise. testsuite/ChangeLog: 2010-10-19 Ken Werner * gdb.base/gnu_vector.exp: Adjust expect messages. Index: gdb/c-valprint.c =================================================================== RCS file: /cvs/src/src/gdb/c-valprint.c,v retrieving revision 1.74 diff -p -u -r1.74 c-valprint.c --- gdb/c-valprint.c 15 Oct 2010 18:54:12 -0000 1.74 +++ gdb/c-valprint.c 19 Oct 2010 11:00:18 -0000 @@ -171,8 +171,13 @@ c_val_print (struct type *type, const gd elttype = check_typedef (unresolved_elttype); if (TYPE_LENGTH (type) > 0 && TYPE_LENGTH (unresolved_elttype) > 0) { + LONGEST low_bound, high_bound; + + if (!get_array_bounds(type, &low_bound, &high_bound)) + error (_("Could not determine the array high bound")); + eltlen = TYPE_LENGTH (elttype); - len = TYPE_LENGTH (type) / eltlen; + len = high_bound - low_bound + 1; if (options->prettyprint_arrays) { print_spaces_filtered (2 + 2 * recurse, stream); Index: gdb/dwarf2read.c =================================================================== RCS file: /cvs/src/src/gdb/dwarf2read.c,v retrieving revision 1.472 diff -p -u -r1.472 dwarf2read.c --- gdb/dwarf2read.c 17 Oct 2010 18:49:46 -0000 1.472 +++ gdb/dwarf2read.c 19 Oct 2010 11:00:18 -0000 @@ -7194,6 +7194,19 @@ read_array_type (struct die_info *die, s if (attr) make_vector_type (type); + /* The DIE may have DW_AT_byte_size set. For example an OpenCL + implementation may choose to implement triple vectors using this + attribute. */ + attr = dwarf2_attr (die, DW_AT_byte_size, cu); + if (attr) + { + if (DW_UNSND (attr) >= TYPE_LENGTH (type)) + TYPE_LENGTH (type) = DW_UNSND (attr); + else + complaint (&symfile_complaints, _("\ +DW_AT_byte_size for array type smaller than the total size of elements")); + } + name = dwarf2_name (die, cu); if (name) TYPE_NAME (type) = name; Index: gdb/gdbtypes.c =================================================================== RCS file: /cvs/src/src/gdb/gdbtypes.c,v retrieving revision 1.203 diff -p -u -r1.203 gdbtypes.c --- gdb/gdbtypes.c 15 Oct 2010 17:48:47 -0000 1.203 +++ gdb/gdbtypes.c 19 Oct 2010 11:00:19 -0000 @@ -802,6 +802,50 @@ get_discrete_bounds (struct type *type, } } +/* Assuming TYPE is a simple, non-empty array type, compute its upper + and lower bound. Save the low bound into LOW_BOUND if not NULL. + Save the high bound into HIGH_BOUND if not NULL. + + Return 1 if the operation was successful. Return zero otherwise, + in which case the values of LOW_BOUND and HIGH_BOUNDS are unmodified. + + We now simply use get_discrete_bounds call to get the values + of the low and high bounds. + get_discrete_bounds can return three values: + 1, meaning that index is a range, + 0, meaning that index is a discrete type, + or -1 for failure. */ + +int +get_array_bounds (struct type *type, LONGEST *low_bound, LONGEST *high_bound) +{ + struct type *index = TYPE_INDEX_TYPE (type); + LONGEST low = 0; + LONGEST high = 0; + int res; + + if (index == NULL) + return 0; + + res = get_discrete_bounds (index, &low, &high); + if (res == -1) + return 0; + + /* Check if the array bounds are undefined. */ + if (res == 1 + && ((low_bound && TYPE_ARRAY_LOWER_BOUND_IS_UNDEFINED (type)) + || (high_bound && TYPE_ARRAY_UPPER_BOUND_IS_UNDEFINED (type)))) + return 0; + + if (low_bound) + *low_bound = low; + + if (high_bound) + *high_bound = high; + + return 1; +} + /* Create an array type using either a blank type supplied in RESULT_TYPE, or creating a new type, inheriting the objfile from RANGE_TYPE. Index: gdb/gdbtypes.h =================================================================== RCS file: /cvs/src/src/gdb/gdbtypes.h,v retrieving revision 1.137 diff -p -u -r1.137 gdbtypes.h --- gdb/gdbtypes.h 15 Oct 2010 17:48:47 -0000 1.137 +++ gdb/gdbtypes.h 19 Oct 2010 11:00:19 -0000 @@ -1383,6 +1383,9 @@ extern int get_vptr_fieldno (struct type extern int get_discrete_bounds (struct type *, LONGEST *, LONGEST *); +extern int get_array_bounds (struct type *type, LONGEST *low_bound, + LONGEST *high_bound); + extern int class_types_same_p (const struct type *, const struct type *); extern int is_ancestor (struct type *, struct type *); Index: gdb/valarith.c =================================================================== RCS file: /cvs/src/src/gdb/valarith.c,v retrieving revision 1.87 diff -p -u -r1.87 valarith.c --- gdb/valarith.c 8 Oct 2010 16:50:53 -0000 1.87 +++ gdb/valarith.c 19 Oct 2010 11:00:19 -0000 @@ -1388,7 +1388,8 @@ vector_binop (struct value *val1, struct { struct value *val, *tmp, *mark; struct type *type1, *type2, *eltype1, *eltype2, *result_type; - int t1_is_vec, t2_is_vec, elsize, n, i; + int t1_is_vec, t2_is_vec, elsize, i; + LONGEST low_bound1, high_bound1, low_bound2, high_bound2; type1 = check_typedef (value_type (val1)); type2 = check_typedef (value_type (val2)); @@ -1401,23 +1402,23 @@ vector_binop (struct value *val1, struct if (!t1_is_vec || !t2_is_vec) error (_("Vector operations are only supported among vectors")); + if (!get_array_bounds (type1, &low_bound1, &high_bound1) + || !get_array_bounds (type2, &low_bound2, &high_bound2)) + error (_("Could not determine the vector bounds")); + eltype1 = check_typedef (TYPE_TARGET_TYPE (type1)); eltype2 = check_typedef (TYPE_TARGET_TYPE (type2)); + elsize = TYPE_LENGTH (eltype1); if (TYPE_CODE (eltype1) != TYPE_CODE (eltype2) - || TYPE_LENGTH (eltype1) != TYPE_LENGTH (eltype2) - || TYPE_UNSIGNED (eltype1) != TYPE_UNSIGNED (eltype2)) + || elsize != TYPE_LENGTH (eltype2) + || TYPE_UNSIGNED (eltype1) != TYPE_UNSIGNED (eltype2) + || low_bound1 != low_bound2 || high_bound1 != high_bound2) error (_("Cannot perform operation on vectors with different types")); - elsize = TYPE_LENGTH (eltype1); - n = TYPE_LENGTH (type1) / elsize; - - if (n != TYPE_LENGTH (type2) / TYPE_LENGTH (eltype2)) - error (_("Cannot perform operation on vectors with different sizes")); - val = allocate_value (type1); mark = value_mark (); - for (i = 0; i < n; i++) + for (i = 0; i < high_bound1 - low_bound1 + 1; i++) { tmp = value_binop (value_subscript (val1, i), value_subscript (val2, i), op); Index: gdb/valops.c =================================================================== RCS file: /cvs/src/src/gdb/valops.c,v retrieving revision 1.252 diff -p -u -r1.252 valops.c --- gdb/valops.c 8 Oct 2010 16:50:53 -0000 1.252 +++ gdb/valops.c 19 Oct 2010 11:00:19 -0000 @@ -543,14 +543,17 @@ value_cast (struct type *type, struct va /* Widen the scalar to a vector. */ struct type *eltype; struct value *val; - int i, n; + LONGEST low_bound, high_bound; + int i; + if (!get_array_bounds (type, &low_bound, &high_bound)) + error (_("Could not determine the vector bounds")); + eltype = check_typedef (TYPE_TARGET_TYPE (type)); arg2 = value_cast (eltype, arg2); val = allocate_value (type); - n = TYPE_LENGTH (type) / TYPE_LENGTH (eltype); - for (i = 0; i < n; i++) + for (i = 0; i < high_bound - low_bound + 1; i++) { /* Duplicate the contents of arg2 into the destination vector. */ memcpy (value_contents_writeable (val) + (i * TYPE_LENGTH (eltype)), Index: gdb/valprint.c =================================================================== RCS file: /cvs/src/src/gdb/valprint.c,v retrieving revision 1.97 diff -p -u -r1.97 valprint.c --- gdb/valprint.c 18 Oct 2010 19:14:02 -0000 1.97 +++ gdb/valprint.c 19 Oct 2010 11:00:19 -0000 @@ -1067,44 +1067,6 @@ print_char_chars (struct ui_file *stream } } -/* Assuming TYPE is a simple, non-empty array type, compute its upper - and lower bound. Save the low bound into LOW_BOUND if not NULL. - Save the high bound into HIGH_BOUND if not NULL. - - Return 1 if the operation was successful. Return zero otherwise, - in which case the values of LOW_BOUND and HIGH_BOUNDS are unmodified. - - We now simply use get_discrete_bounds call to get the values - of the low and high bounds. - get_discrete_bounds can return three values: - 1, meaning that index is a range, - 0, meaning that index is a discrete type, - or -1 for failure. */ - -int -get_array_bounds (struct type *type, LONGEST *low_bound, LONGEST *high_bound) -{ - struct type *index = TYPE_INDEX_TYPE (type); - LONGEST low = 0; - LONGEST high = 0; - int res; - - if (index == NULL) - return 0; - - res = get_discrete_bounds (index, &low, &high); - if (res == -1) - return 0; - - if (low_bound) - *low_bound = low; - - if (high_bound) - *high_bound = high; - - return 1; -} - /* Print on STREAM using the given OPTIONS the index for the element at INDEX of an array whose index type is INDEX_TYPE. */ @@ -1149,38 +1111,19 @@ val_print_array_elements (struct type *t unsigned int rep1; /* Number of repetitions we have detected so far. */ unsigned int reps; - LONGEST low_bound_index = 0; + LONGEST low_bound, high_bound; elttype = TYPE_TARGET_TYPE (type); eltlen = TYPE_LENGTH (check_typedef (elttype)); index_type = TYPE_INDEX_TYPE (type); - /* Compute the number of elements in the array. On most arrays, - the size of its elements is not zero, and so the number of elements - is simply the size of the array divided by the size of the elements. - But for arrays of elements whose size is zero, we need to look at - the bounds. */ - if (eltlen != 0) - len = TYPE_LENGTH (type) / eltlen; + if (get_array_bounds (type, &low_bound, &high_bound)) + len = high_bound - low_bound + 1; else { - LONGEST low, hi; - - if (get_array_bounds (type, &low, &hi)) - len = hi - low + 1; - else - { - warning (_("unable to get bounds of array, assuming null array")); - len = 0; - } - } - - /* Get the array low bound. This only makes sense if the array - has one or more element in it. */ - if (len > 0 && !get_array_bounds (type, &low_bound_index, NULL)) - { - warning (_("unable to get low bound of array, using zero as default")); - low_bound_index = 0; + warning (_("unable to get bounds of array, assuming null array")); + low_bound = 0; + len = 0; } annotate_array_section_begin (i, elttype); @@ -1200,7 +1143,7 @@ val_print_array_elements (struct type *t } } wrap_here (n_spaces (2 + 2 * recurse)); - maybe_print_array_index (index_type, i + low_bound_index, + maybe_print_array_index (index_type, i + low_bound, stream, options); rep1 = i + 1; Index: gdb/valprint.h =================================================================== RCS file: /cvs/src/src/gdb/valprint.h,v retrieving revision 1.27 diff -p -u -r1.27 valprint.h --- gdb/valprint.h 11 Jun 2010 15:36:05 -0000 1.27 +++ gdb/valprint.h 19 Oct 2010 11:00:19 -0000 @@ -109,9 +109,6 @@ extern void get_raw_print_options (struc extern void get_formatted_print_options (struct value_print_options *opts, char format); -extern int get_array_bounds (struct type *type, LONGEST *low_bound, - LONGEST *high_bound); - extern void maybe_print_array_index (struct type *index_type, LONGEST index, struct ui_file *stream, const struct value_print_options *options); Index: gdb/testsuite/gdb.base/gnu_vector.exp =================================================================== RCS file: /cvs/src/src/gdb/testsuite/gdb.base/gnu_vector.exp,v retrieving revision 1.3 diff -p -u -r1.3 gnu_vector.exp --- gdb/testsuite/gdb.base/gnu_vector.exp 8 Oct 2010 16:50:55 -0000 1.3 +++ gdb/testsuite/gdb.base/gnu_vector.exp 19 Oct 2010 11:00:19 -0000 @@ -119,8 +119,8 @@ gdb_test "print f4a + d2" "Cannot perfor gdb_test "print d2 + f4a" "Cannot perform operation on vectors with different types" gdb_test "print ui4 + i4a" "Cannot perform operation on vectors with different types" gdb_test "print i4a + ui4" "Cannot perform operation on vectors with different types" -gdb_test "print i4a + i2" "Cannot perform operation on vectors with different sizes" -gdb_test "print i2 + i4a" "Cannot perform operation on vectors with different sizes" -gdb_test "print f4a + f2" "Cannot perform operation on vectors with different sizes" -gdb_test "print f2 + f4a" "Cannot perform operation on vectors with different sizes" +gdb_test "print i4a + i2" "Cannot perform operation on vectors with different types" +gdb_test "print i2 + i4a" "Cannot perform operation on vectors with different types" +gdb_test "print f4a + f2" "Cannot perform operation on vectors with different types" +gdb_test "print f2 + f4a" "Cannot perform operation on vectors with different types" --Boundary-00=_N/XvMeK8j1EQ+39--