From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 2103) id 72F5E385084B; Fri, 24 Mar 2023 14:08:56 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 72F5E385084B Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable From: Nick Alcock To: bfd-cvs@sourceware.org, gdb-cvs@sourceware.org Subject: [binutils-gdb] libctf: get the offsets of fields of unnamed structs/unions right X-Act-Checkin: binutils-gdb X-Git-Author: Nick Alcock X-Git-Refname: refs/heads/master X-Git-Oldrev: 04d91c807eaf4395472409a53e2acd9ad89683f0 X-Git-Newrev: 3672e3262210d1a08a3fdc44569ea8b5696c43cc Message-Id: <20230324140856.72F5E385084B@sourceware.org> Date: Fri, 24 Mar 2023 14:08:56 +0000 (GMT) X-BeenThere: binutils-cvs@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Binutils-cvs mailing list List-Unsubscribe: , List-Archive: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 24 Mar 2023 14:08:56 -0000 https://sourceware.org/git/gitweb.cgi?p=3Dbinutils-gdb.git;h=3D3672e3262210= d1a08a3fdc44569ea8b5696c43cc commit 3672e3262210d1a08a3fdc44569ea8b5696c43cc Author: Nick Alcock Date: Thu Mar 23 00:15:17 2023 +0000 libctf: get the offsets of fields of unnamed structs/unions right =20 We were failing to add the offsets of the containing struct/union in this case, leading to all offsets being relative to the unnamed struct/union itself. =20 libctf/ PR libctf/30264 * ctf-types.c (ctf_member_info): Add the offset of the unnamed member of the current struct as necessary. * testsuite/libctf-lookup/unnamed-field-info*: New test. Diff: --- libctf/ctf-types.c | 5 +- .../libctf-lookup/unnamed-field-info-ctf.c | 36 ++++++++++ .../testsuite/libctf-lookup/unnamed-field-info.c | 79 ++++++++++++++++++= ++++ .../testsuite/libctf-lookup/unnamed-field-info.lk | 2 + 4 files changed, 121 insertions(+), 1 deletion(-) diff --git a/libctf/ctf-types.c b/libctf/ctf-types.c index d21f6d5ff99..dd82053e1d7 100644 --- a/libctf/ctf-types.c +++ b/libctf/ctf-types.c @@ -1417,7 +1417,10 @@ ctf_member_info (ctf_dict_t *fp, ctf_id_t type, cons= t char *name, && (ctf_type_kind (fp, memb.ctlm_type) =3D=3D CTF_K_STRUCT || ctf_type_kind (fp, memb.ctlm_type) =3D=3D CTF_K_UNION) && (ctf_member_info (fp, memb.ctlm_type, name, mip) =3D=3D 0)) - return 0; + { + mip->ctm_offset +=3D (unsigned long) CTF_LMEM_OFFSET (&memb); + return 0; + } =20 if (strcmp (membname, name) =3D=3D 0) { diff --git a/libctf/testsuite/libctf-lookup/unnamed-field-info-ctf.c b/libc= tf/testsuite/libctf-lookup/unnamed-field-info-ctf.c new file mode 100644 index 00000000000..54d60f5b195 --- /dev/null +++ b/libctf/testsuite/libctf-lookup/unnamed-field-info-ctf.c @@ -0,0 +1,36 @@ +struct A +{ + int a; + char *b; + struct + { + struct + { + char *one; + int two; + }; + union + { + char *three; + }; + }; + struct + { + int four; + }; + union + { + struct + { + double x; + long y; + }; + struct + { + struct { char *foo; } z; + float aleph; + }; + }; +}; + +struct A used; diff --git a/libctf/testsuite/libctf-lookup/unnamed-field-info.c b/libctf/t= estsuite/libctf-lookup/unnamed-field-info.c new file mode 100644 index 00000000000..9abe8b026bb --- /dev/null +++ b/libctf/testsuite/libctf-lookup/unnamed-field-info.c @@ -0,0 +1,79 @@ +/* Make sure unnamed field offsets are relative to the containing struct. = */ + +#include +#include +#include +#include + +#include "unnamed-field-info-ctf.c" + +static void +verify_offsetof_matching (ctf_dict_t *fp, ctf_id_t type, const char *name,= size_t offset) +{ + ctf_membinfo_t mi; + + if (ctf_member_info (fp, type, name, &mi) < 0) + goto err; + + if (mi.ctm_offset !=3D offset * 8) + fprintf (stderr, "field %s inconsistency: offsetof() says %zi bits, CT= F says %zi\n", + name, offset * 8, mi.ctm_offset); + + return; + + err: + fprintf (stderr, "Cannot look up field %s: %s\n", name, + ctf_errmsg (ctf_errno (fp))); + return; +} + +int +main (int argc, char *argv[]) +{ + ctf_dict_t *fp; + ctf_archive_t *ctf; + ctf_id_t type; + int err; + + if (argc !=3D 2) + { + fprintf (stderr, "Syntax: %s PROGRAM\n", argv[0]); + exit(1); + } + + if ((ctf =3D ctf_open (argv[1], NULL, &err)) =3D=3D NULL) + goto open_err; + if ((fp =3D ctf_dict_open (ctf, NULL, &err)) =3D=3D NULL) + goto open_err; + + /* Dig out some structure members by name. */ + + if ((type =3D ctf_lookup_by_name (fp, "struct A") ) =3D=3D CTF_ERR) + goto err; + + verify_offsetof_matching (fp, type, "a", offsetof (struct A, a)); + verify_offsetof_matching (fp, type, "b", offsetof (struct A, b)); + verify_offsetof_matching (fp, type, "one", offsetof (struct A, one)); + verify_offsetof_matching (fp, type, "two", offsetof (struct A, two)); + verify_offsetof_matching (fp, type, "three", offsetof (struct A, three)); + verify_offsetof_matching (fp, type, "four", offsetof (struct A, four)); + verify_offsetof_matching (fp, type, "x", offsetof (struct A, x)); + verify_offsetof_matching (fp, type, "y", offsetof (struct A, y)); + verify_offsetof_matching (fp, type, "z", offsetof (struct A, z)); + verify_offsetof_matching (fp, type, "aleph", offsetof (struct A, aleph)); + + ctf_dict_close (fp); + ctf_arc_close (ctf); + + printf ("Offset validation complete.\n"); + + return 0; + + open_err: + fprintf (stderr, "%s: cannot open: %s\n", argv[0], ctf_errmsg (err)); + return 1; + + err: + fprintf (stderr, "Cannot look up type: %s\n", ctf_errmsg (ctf_errno (fp)= )); + return 1; +} diff --git a/libctf/testsuite/libctf-lookup/unnamed-field-info.lk b/libctf/= testsuite/libctf-lookup/unnamed-field-info.lk new file mode 100644 index 00000000000..eae6a517d50 --- /dev/null +++ b/libctf/testsuite/libctf-lookup/unnamed-field-info.lk @@ -0,0 +1,2 @@ +# source: unnamed-field-info-ctf.c +Offset validation complete.