From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 2727 invoked by alias); 8 May 2014 19:01:18 -0000 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 Received: (qmail 2713 invoked by uid 89); 8 May 2014 19:01:17 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.6 required=5.0 tests=BAYES_00,FREEMAIL_FROM,MIME_QP_LONG_LINE,RCVD_IN_DNSWL_LOW,SPF_PASS autolearn=ham version=3.3.2 X-HELO: mail-pa0-f48.google.com Received: from mail-pa0-f48.google.com (HELO mail-pa0-f48.google.com) (209.85.220.48) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES128-SHA encrypted) ESMTPS; Thu, 08 May 2014 19:01:16 +0000 Received: by mail-pa0-f48.google.com with SMTP id rd3so3239662pab.7 for ; Thu, 08 May 2014 12:01:14 -0700 (PDT) X-Received: by 10.66.188.5 with SMTP id fw5mr1096678pac.63.1399575674264; Thu, 08 May 2014 12:01:14 -0700 (PDT) Received: from [10.0.0.142] ([74.61.156.65]) by mx.google.com with ESMTPSA id kj1sm3363604pbd.20.2014.05.08.12.01.12 for (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Thu, 08 May 2014 12:01:13 -0700 (PDT) References: <1399574816-12845-1-git-send-email-tromey@redhat.com> <1399574816-12845-3-git-send-email-tromey@redhat.com> Mime-Version: 1.0 (1.0) In-Reply-To: <1399574816-12845-3-git-send-email-tromey@redhat.com> Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: quoted-printable Message-Id: <14B6B8AB-EE5F-476D-BA19-158C9AF39B57@gmail.com> Cc: "gdb-patches@sourceware.org" From: pinskia@gmail.com Subject: Re: [PATCH 2/2] handle VLA in a struct or union Date: Thu, 08 May 2014 19:01:00 -0000 To: Tom Tromey X-IsSubscribed: yes X-SW-Source: 2014-05/txt/msg00098.txt.bz2 > On May 8, 2014, at 11:46 AM, Tom Tromey wrote: >=20 > It is valid in C to have a VLA in a struct or union type, but gdb did > not handle this. In GNU C only. It is extension. Thanks, Andrew >=20 > This patch adds support for these cases in the obvious way. >=20 > Built and regtested on x86-64 Fedora 20. > New tests included. >=20 > However, before this goes in, I'd like to understand the oddity > pointed out by a change in is_dynamic_type. That is, this test: >=20 > /* This can happen with Ada for reasons unknown. */ > && TYPE_FIELD_TYPE (type, i) !=3D NULL >=20 > is needed to avoid a crash with the Ada "iwide.exp" test. This type: >=20 > (top-gdb) p real_type.main_type.name > $15 =3D 0x7ffff0354c6d "ada__tags__type_specific_data___XVE" >=20 > ... has a seemingly invalid field: >=20 > (top-gdb) p real_type.main_type.nfields > $9 =3D 13 > [...] > (top-gdb) p real_type.main_type.flds_bnds.fields[12] > $12 =3D { > loc =3D { > bitpos =3D 576, > enumval =3D 576, > physaddr =3D 576, > physname =3D 0x240
, > dwarf_block =3D 0x240 > }, > artificial =3D 0, > loc_kind =3D FIELD_LOC_KIND_BITPOS, > bitsize =3D 0, > type =3D 0x0, > name =3D 0x0 > } >=20 > Joel, can you comment? Thanks. >=20 > 2014-05-08 Tom Tromey >=20 > * gdbtypes.c (is_dynamic_type, resolve_dynamic_type) > : New cases. >=20 > 2014-05-08 Tom Tromey >=20 > * gdb.base/vla-datatypes.exp: Add tests for VLA-in-structure and > VLA-in-union. > * gdb.base/vla-datatypes.c (vla_factory): Add vla_struct, > vla_union types. Initialize objects of those types and compute > their sizes. > --- > gdb/ChangeLog | 5 ++ > gdb/gdbtypes.c | 94 +++++++++++++++++++++++++++= +++++ > gdb/testsuite/ChangeLog | 8 +++ > gdb/testsuite/gdb.base/vla-datatypes.c | 16 ++++++ > gdb/testsuite/gdb.base/vla-datatypes.exp | 14 +++++ > 5 files changed, 137 insertions(+) >=20 > diff --git a/gdb/gdbtypes.c b/gdb/gdbtypes.c > index 95b861e..59f354a 100644 > --- a/gdb/gdbtypes.c > +++ b/gdb/gdbtypes.c > @@ -1636,6 +1636,20 @@ is_dynamic_type (struct type *type) > return 1; > return is_dynamic_type (TYPE_TARGET_TYPE (type)); > } > + > + case TYPE_CODE_STRUCT: > + case TYPE_CODE_UNION: > + { > + int i; > + > + for (i =3D 0; i < TYPE_NFIELDS (type); ++i) > + if (!field_is_static (&TYPE_FIELD (type, i)) > + /* This can happen with Ada for reasons unknown. */ > + && TYPE_FIELD_TYPE (type, i) !=3D NULL > + && is_dynamic_type (TYPE_FIELD_TYPE (type, i))) > + return 1; > + } > + break; > } >=20 > return 0; > @@ -1753,6 +1767,86 @@ resolve_dynamic_type (struct type *type, CORE_ADDR= addr) > case TYPE_CODE_RANGE: > resolved_type =3D resolve_dynamic_range (type); > break; > + > + case TYPE_CODE_UNION: > + { > + int i; > + unsigned int max_len; > + > + resolved_type =3D copy_type (type); > + TYPE_FIELDS (resolved_type) > + =3D TYPE_ALLOC (resolved_type, > + TYPE_NFIELDS (resolved_type) * sizeof (struct field)); > + memcpy (TYPE_FIELDS (resolved_type), > + TYPE_FIELDS (type), > + TYPE_NFIELDS (resolved_type) * sizeof (struct field)); > + for (i =3D 0; i < TYPE_NFIELDS (resolved_type); ++i) > + { > + struct type *t; > + > + if (field_is_static (&TYPE_FIELD (type, i))) > + continue; > + > + t =3D resolve_dynamic_type (TYPE_FIELD_TYPE (resolved_type, i), > + addr); > + > + TYPE_FIELD_TYPE (resolved_type, i) =3D t; > + if (TYPE_LENGTH (t) > max_len) > + max_len =3D TYPE_LENGTH (t); > + } > + > + TYPE_LENGTH (resolved_type) =3D max_len; > + } > + break; > + > + case TYPE_CODE_STRUCT: > + { > + int i; > + int vla_field =3D TYPE_NFIELDS (type) - 1; > + > + resolved_type =3D copy_type (type); > + TYPE_FIELDS (resolved_type) > + =3D TYPE_ALLOC (resolved_type, > + TYPE_NFIELDS (resolved_type) * sizeof (struct field)); > + memcpy (TYPE_FIELDS (resolved_type), > + TYPE_FIELDS (type), > + TYPE_NFIELDS (resolved_type) * sizeof (struct field)); > + for (i =3D 0; i < TYPE_NFIELDS (resolved_type); ++i) > + { > + struct type *t; > + > + if (field_is_static (&TYPE_FIELD (type, i))) > + continue; > + > + t =3D resolve_dynamic_type (TYPE_FIELD_TYPE (resolved_type, i), > + addr); > + > + /* This is a bit odd. We do not support a VLA in any > + position of a struct except for the last. GCC does > + have an extension that allows a VLA in the middle of a > + structure, but the DWARF it emits is relatively useless > + to us, so we can't represent such a type properly -- > + and even if we could, we do not have enough information > + to redo structure layout anyway. Nevertheless, we > + check all the fields in case something odd slips > + through, since it's better to see an error than > + incorrect results. */ > + if (t !=3D TYPE_FIELD_TYPE (resolved_type, i) > + && i !=3D vla_field) > + error (_("Attempt to resolve a variably-sized type which appea= rs " > + "in the interior of a structure type")); > + > + TYPE_FIELD_TYPE (resolved_type, i) =3D t; > + } > + > + /* Due to the above restrictions we can successfully compute > + the size of the resulting structure here, as the offset of > + the final field plus its size. */ > + TYPE_LENGTH (resolved_type) > + =3D (TYPE_FIELD_BITPOS (resolved_type, vla_field) / TARGET_CHAR_BIT > + + TYPE_LENGTH (TYPE_FIELD_TYPE (resolved_type, vla_field))); > + } > + break; > } >=20 > return resolved_type; > diff --git a/gdb/testsuite/gdb.base/vla-datatypes.c b/gdb/testsuite/gdb.b= ase/vla-datatypes.c > index 51e342e..8561a4e 100644 > --- a/gdb/testsuite/gdb.base/vla-datatypes.c > +++ b/gdb/testsuite/gdb.base/vla-datatypes.c > @@ -46,6 +46,18 @@ vla_factory (int n) > BAR bar_vla[n]; > int i; >=20 > + struct vla_struct > + { > + int something; > + int vla_field[n]; > + } vla_struct_object; > + > + union vla_union > + { > + int vla_field[n]; > + } vla_union_object; > + > + vla_struct_object.something =3D n; > for (i =3D 0; i < n; i++) > { > int_vla[i] =3D i*2; > @@ -61,6 +73,8 @@ vla_factory (int n) > foo_vla[i].a =3D i*2; > bar_vla[i].x =3D i*2; > bar_vla[i].y.a =3D i*2; > + vla_struct_object.vla_field[i] =3D i*2; > + vla_union_object.vla_field[i] =3D i*2; > } >=20 > size_t int_size =3D sizeof(int_vla); /* vlas_filled */ > @@ -74,6 +88,8 @@ vla_factory (int n) > size_t uchar_size =3D sizeof(unsigned_char_vla); > size_t foo_size =3D sizeof(foo_vla); > size_t bar_size =3D sizeof(bar_vla); > + size_t vla_struct_object_size =3D sizeof(vla_struct_object); > + size_t vla_union_object_size =3D sizeof(vla_union_object); >=20 > return; /* break_end_of_vla_factory */ > } > diff --git a/gdb/testsuite/gdb.base/vla-datatypes.exp b/gdb/testsuite/gdb= .base/vla-datatypes.exp > index 8247658..36af38d 100644 > --- a/gdb/testsuite/gdb.base/vla-datatypes.exp > +++ b/gdb/testsuite/gdb.base/vla-datatypes.exp > @@ -53,6 +53,10 @@ gdb_test "print foo_vla" \ > gdb_test "print bar_vla" \ > "\\\{\\\{x =3D 0, y =3D \\\{a =3D 0\\\}\\\}, \\\{x =3D 2, y =3D = \\\{a =3D 2\\\}\\\}, \\\{x =3D 4, y =3D \\\{a =3D 4\\\}\\\}, \\\{x =3D 6, y= =3D \\\{a =3D 6\\\}\\\}, \\\{x =3D 8, y =3D \\\{a =3D 8\\\}\\\}\\\}" \ > "print bar_vla" > +gdb_test "print vla_struct_object" \ > + "\\\{something =3D 5, vla_field =3D \\\{0, 2, 4, 6, 8\\\}\\\}" > +gdb_test "print vla_union_object" \ > + "\\\{vla_field =3D \\\{0, 2, 4, 6, 8\\\}\\\}" >=20 > # Check whatis of VLA's. > gdb_test "whatis int_vla" "type =3D int \\\[5\\\]" "whatis int_vla" > @@ -74,6 +78,8 @@ gdb_test "whatis unsigned_char_vla" "type =3D unsigned = char \\\[5\\\]" \ > "whatis unsigned_char_vla" > gdb_test "whatis foo_vla" "type =3D struct foo \\\[5\\\]" "whatis foo_vla" > gdb_test "whatis bar_vla" "type =3D BAR \\\[5\\\]" "whatis bar_vla" > +gdb_test "whatis vla_struct_object" "type =3D struct vla_struct" > +gdb_test "whatis vla_union_object" "type =3D union vla_union" >=20 > # Check ptype of VLA's. > gdb_test "ptype int_vla" "type =3D int \\\[5\\\]" "ptype int_vla" > @@ -96,6 +102,10 @@ gdb_test "ptype foo_vla" "type =3D struct foo {\r\n\\= s+int a;\r\n} \\\[5\\\]" \ > gdb_test "ptype bar_vla" \ > "type =3D struct bar {\r\n\\s+int x;\r\n\\s+struct foo y;\r\n} \= \\[5\\\]" \ > "ptype bar_vla" > +gdb_test "ptype vla_struct_object" \ > + "type =3D struct vla_struct {\r\n\\s+int something;\r\n\\s+int vla_f= ield\\\[5\\\];\r\n}" > +gdb_test "ptype vla_union_object" \ > + "type =3D union vla_union {\r\n\\s+int vla_field\\\[5\\\];\r\n}" >=20 > # Check the size of the VLA's. > gdb_breakpoint [gdb_get_line_number "break_end_of_vla_factory"] > @@ -119,6 +129,10 @@ gdb_test "print uchar_size =3D=3D sizeof(unsigned_ch= ar_vla)" " =3D 1" \ > "size of unsigned_char_vla" > gdb_test "print foo_size =3D=3D sizeof(foo_vla)" " =3D 1" "size of foo_vl= a" > gdb_test "print bar_size =3D=3D sizeof(bar_vla)" " =3D 1" "size of bar_vl= a" > +gdb_test "print vla_struct_object_size =3D=3D sizeof(vla_struct_object)"= \ > + " =3D 1" "size of vla_struct_object" > +gdb_test "print vla_union_object_size =3D=3D sizeof(vla_union_object)" \ > + " =3D 1" "size of vla_union_object" >=20 > # Check side effects for sizeof argument. > set sizeof_int [get_sizeof "int" 4] > --=20 > 1.9.0 >=20