Skip to content

Commit fa4fe27

Browse files
committed
libctf: fix cv-qualified unnamed struct/union field lookup
GCC permits not only unnamed structs and unions, but cv-qualified ones. Our earlier fix in 6c3a387 supported unnamed structs and unions, but only unqualified ones. Resolving away cvr-quals of nameless fields (and, irrelevantly, typedefs) is easy and fixes this problem. Tests adjusted accordingly. libctf/ PR libctf/32746 * ctf-types.c (ctf_member_next): Resolve away cv-quals. (ctf_member_info): Likewise. * testsuite/libctf-lookup/struct-iteration-ctf.c: Add a cv-qualified type or two: make sure to keep a non-qualified one. * testsuite/libctf-lookup/struct-iteration.c: Verify consistency of ctf_member_next and ctf_member_info. * testsuite/libctf-lookup/struct-iteration.lk: Adjust. Tested-by: Stephen Brennan <[email protected]>
1 parent 83e8a5d commit fa4fe27

File tree

4 files changed

+55
-13
lines changed

4 files changed

+55
-13
lines changed

libctf/ctf-types.c

Lines changed: 26 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -187,10 +187,21 @@ ctf_member_next (ctf_dict_t *fp, ctf_id_t type, ctf_next_t **it,
187187
*membtype = memb.ctlm_type;
188188
offset = (unsigned long) CTF_LMEM_OFFSET (&memb);
189189

190-
if (membname[0] == 0
191-
&& (ctf_type_kind (fp, memb.ctlm_type) == CTF_K_STRUCT
192-
|| ctf_type_kind (fp, memb.ctlm_type) == CTF_K_UNION))
193-
i->ctn_type = memb.ctlm_type;
190+
if (membname[0] == 0)
191+
{
192+
ctf_id_t resolved;
193+
194+
if ((resolved = ctf_type_resolve (fp, memb.ctlm_type)) == CTF_ERR)
195+
{
196+
if (ctf_errno (fp) != ECTF_NONREPRESENTABLE)
197+
return -1; /* errno is set for us. */
198+
resolved = memb.ctlm_type;
199+
}
200+
201+
if (ctf_type_kind (fp, resolved) == CTF_K_STRUCT
202+
|| ctf_type_kind (fp, resolved) == CTF_K_UNION)
203+
i->ctn_type = resolved;
204+
}
194205
i->ctn_n++;
195206

196207
/* The callers might want automatic recursive sub-struct traversal. */
@@ -1406,16 +1417,24 @@ ctf_member_info (ctf_dict_t *fp, ctf_id_t type, const char *name,
14061417
{
14071418
ctf_lmember_t memb;
14081419
const char *membname;
1420+
ctf_id_t resolved;
14091421

14101422
if (ctf_struct_member (fp, &memb, tp, vlen, vbytes, i) < 0)
14111423
return (ctf_set_errno (ofp, ctf_errno (fp)));
14121424

14131425
membname = ctf_strptr (fp, memb.ctlm_name);
14141426

1427+
if ((resolved = ctf_type_resolve (fp, memb.ctlm_type)) == CTF_ERR)
1428+
{
1429+
if (ctf_errno (fp) != ECTF_NONREPRESENTABLE)
1430+
return (ctf_set_errno (ofp, ctf_errno (fp)));
1431+
resolved = memb.ctlm_type;
1432+
}
1433+
14151434
if (membname[0] == 0
1416-
&& (ctf_type_kind (fp, memb.ctlm_type) == CTF_K_STRUCT
1417-
|| ctf_type_kind (fp, memb.ctlm_type) == CTF_K_UNION)
1418-
&& (ctf_member_info (fp, memb.ctlm_type, name, mip) == 0))
1435+
&& (ctf_type_kind (fp, resolved) == CTF_K_STRUCT
1436+
|| ctf_type_kind (fp, resolved) == CTF_K_UNION)
1437+
&& (ctf_member_info (fp, resolved, name, mip) == 0))
14191438
{
14201439
mip->ctm_offset += (unsigned long) CTF_LMEM_OFFSET (&memb);
14211440
return 0;

libctf/testsuite/libctf-lookup/struct-iteration-ctf.c

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,19 +6,22 @@ struct foo_t
66
size_t bar;
77
const char *baz;
88
struct foo_t *self;
9-
union
9+
const volatile union
1010
{
1111
double should_not_appear;
1212
char *nor_should_this;
1313
} named;
14-
struct
14+
volatile const struct
1515
{
1616
long unnamed_sub_member;
1717
union
1818
{
1919
double one_more_level;
2020
long yes_really_one_more;
2121
};
22+
struct {
23+
int and_finally;
24+
};
2225
};
2326
struct {}; /* Empty ones */
2427
union {};

libctf/testsuite/libctf-lookup/struct-iteration.c

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,11 +51,29 @@ main (int argc, char *argv[])
5151
while ((offset = ctf_member_next (fp, type, &i, &name, &membtype,
5252
CTF_MN_RECURSE)) >= 0)
5353
{
54+
ctf_membinfo_t memb;
5455
char *type_name = ctf_type_aname (fp, membtype);
5556

5657
printf ("next test: %s, offset %zx, has type %lx/%s\n",
5758
name, offset, membtype, type_name);
5859
free (type_name);
60+
61+
/* Check that we can get the same member via ctf_member_info too. */
62+
if (name[0] != '\0')
63+
{
64+
if (ctf_member_info (fp, type, name, &memb) != 0)
65+
{
66+
fprintf (stderr, "Cannot get member info for %s: %s\n",
67+
name, ctf_errmsg (ctf_errno (fp)));
68+
exit (1);
69+
}
70+
if (memb.ctm_offset != offset || memb.ctm_type != membtype)
71+
{
72+
fprintf (stderr, "ctf_member_info versus iteration comparison "
73+
"failure: types %lx/%lx, offsets %zx/%lx\n",
74+
membtype, memb.ctm_type, offset, memb.ctm_offset);
75+
}
76+
}
5977
}
6078
if (ctf_errno (fp) != ECTF_NEXT_END)
6179
goto nerr;

libctf/testsuite/libctf-lookup/struct-iteration.lk

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,21 +4,23 @@ iter test: foo, offset [0-9a-f]*, has type [0-9a-f]*/int
44
iter test: bar, offset [0-9a-f]*, has type [0-9a-f]*/size_t
55
iter test: baz, offset [0-9a-f]*, has type [0-9a-f]*/const char \*
66
iter test: self, offset [0-9a-f]*, has type [0-9a-f]*/struct foo_t \*
7-
iter test: named, offset [0-9a-f]*, has type [0-9a-f]*/union
8-
iter test: , offset [0-9a-f]*, has type [0-9a-f]*/struct
7+
iter test: named, offset [0-9a-f]*, has type [0-9a-f]*/volatile const union
8+
iter test: , offset [0-9a-f]*, has type [0-9a-f]*/volatile const struct
99
iter test: , offset [0-9a-f]*, has type [0-9a-f]*/struct
1010
iter test: , offset [0-9a-f]*, has type [0-9a-f]*/union
1111
iter test: after_the_end, offset [0-9a-f]*, has type [0-9a-f]*/int
1212
next test: foo, offset [0-9a-f]*, has type [0-9a-f]*/int
1313
next test: bar, offset [0-9a-f]*, has type [0-9a-f]*/size_t
1414
next test: baz, offset [0-9a-f]*, has type [0-9a-f]*/const char \*
1515
next test: self, offset [0-9a-f]*, has type [0-9a-f]*/struct foo_t \*
16-
next test: named, offset [0-9a-f]*, has type [0-9a-f]*/union
17-
next test: , offset [0-9a-f]*, has type [0-9a-f]*/struct
16+
next test: named, offset [0-9a-f]*, has type [0-9a-f]*/volatile const union
17+
next test: , offset [0-9a-f]*, has type [0-9a-f]*/volatile const struct
1818
next test: unnamed_sub_member, offset [0-9a-f]*, has type [0-9a-f]*/long int
1919
next test: , offset [0-9a-f]*, has type [0-9a-f]*/union
2020
next test: one_more_level, offset [0-9a-f]*, has type [0-9a-f]*/double
2121
next test: yes_really_one_more, offset [0-9a-f]*, has type [0-9a-f]*/long int
2222
next test: , offset [0-9a-f]*, has type [0-9a-f]*/struct
23+
next test: and_finally, offset [0-9a-f]*, has type [0-9a-f]*/int
24+
next test: , offset [0-9a-f]*, has type [0-9a-f]*/struct
2325
next test: , offset [0-9a-f]*, has type [0-9a-f]*/union
2426
next test: after_the_end, offset [0-9a-f]*, has type [0-9a-f]*/int

0 commit comments

Comments
 (0)