libctf: lookup_by_name: do not return success for nonexistent pointer types
The recent work allowing lookups of pointers in child dicts when the pointed-to type is in the parent dict broke the case where a pointer type that does not exist at all is looked up: we mistakenly return the pointed-to type, which is likely not a pointer at all. This causes considerable confusion. Fixed, with a new testcase. libctf/ChangeLog 2021-01-19 Nick Alcock <nick.alcock@oracle.com> * ctf-lookup.c (ctf_lookup_by_name_internal): Do not return the base type if looking up a nonexistent pointer type. * testsuite/libctf-regression/pptrtab*: Test it.
This commit is contained in:
parent
c98de297b3
commit
e05a3e5a49
5 changed files with 45 additions and 10 deletions
|
@ -1,3 +1,9 @@
|
||||||
|
2021-01-19 Nick Alcock <nick.alcock@oracle.com>
|
||||||
|
|
||||||
|
* ctf-lookup.c (ctf_lookup_by_name_internal): Do not return the
|
||||||
|
base type if looking up a nonexistent pointer type.
|
||||||
|
* testsuite/libctf-regression/pptrtab*: Test it.
|
||||||
|
|
||||||
2021-01-13 Alan Modra <amodra@gmail.com>
|
2021-01-13 Alan Modra <amodra@gmail.com>
|
||||||
|
|
||||||
* Makefile.in: Regenerate.
|
* Makefile.in: Regenerate.
|
||||||
|
|
|
@ -184,24 +184,36 @@ ctf_lookup_by_name_internal (ctf_dict_t *fp, ctf_dict_t *child,
|
||||||
from resolving the type down to its base type and use that instead.
|
from resolving the type down to its base type and use that instead.
|
||||||
This helps with cases where the CTF data includes "struct foo *"
|
This helps with cases where the CTF data includes "struct foo *"
|
||||||
but not "foo_t *" and the user tries to access "foo_t *" in the
|
but not "foo_t *" and the user tries to access "foo_t *" in the
|
||||||
debugger. */
|
debugger.
|
||||||
|
|
||||||
|
There is extra complexity here because uninitialized elements in
|
||||||
|
the pptrtab and ptrtab are set to zero, but zero (as the type ID
|
||||||
|
meaning the unimplemented type) is a valid return type from
|
||||||
|
ctf_lookup_by_name. (Pointers to types are never of type 0, so
|
||||||
|
this is unambiguous, just fiddly to deal with.) */
|
||||||
|
|
||||||
uint32_t idx = LCTF_TYPE_TO_INDEX (fp, type);
|
uint32_t idx = LCTF_TYPE_TO_INDEX (fp, type);
|
||||||
int in_child = 0;
|
int in_child = 0;
|
||||||
|
|
||||||
ntype = type;
|
ntype = CTF_ERR;
|
||||||
if (child && idx <= child->ctf_pptrtab_len)
|
if (child && idx <= child->ctf_pptrtab_len)
|
||||||
{
|
{
|
||||||
ntype = child->ctf_pptrtab[idx];
|
ntype = child->ctf_pptrtab[idx];
|
||||||
if (ntype)
|
if (ntype)
|
||||||
in_child = 1;
|
in_child = 1;
|
||||||
|
else
|
||||||
|
ntype = CTF_ERR;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ntype == 0)
|
if (ntype == CTF_ERR)
|
||||||
ntype = fp->ctf_ptrtab[idx];
|
{
|
||||||
|
ntype = fp->ctf_ptrtab[idx];
|
||||||
|
if (ntype == 0)
|
||||||
|
ntype = CTF_ERR;
|
||||||
|
}
|
||||||
|
|
||||||
/* Try resolving to its base type and check again. */
|
/* Try resolving to its base type and check again. */
|
||||||
if (ntype == 0)
|
if (ntype == CTF_ERR)
|
||||||
{
|
{
|
||||||
if (child)
|
if (child)
|
||||||
ntype = ctf_type_resolve_unsliced (child, type);
|
ntype = ctf_type_resolve_unsliced (child, type);
|
||||||
|
@ -213,16 +225,22 @@ ctf_lookup_by_name_internal (ctf_dict_t *fp, ctf_dict_t *child,
|
||||||
|
|
||||||
idx = LCTF_TYPE_TO_INDEX (fp, ntype);
|
idx = LCTF_TYPE_TO_INDEX (fp, ntype);
|
||||||
|
|
||||||
ntype = 0;
|
ntype = CTF_ERR;
|
||||||
if (child && idx <= child->ctf_pptrtab_len)
|
if (child && idx <= child->ctf_pptrtab_len)
|
||||||
{
|
{
|
||||||
ntype = child->ctf_pptrtab[idx];
|
ntype = child->ctf_pptrtab[idx];
|
||||||
if (ntype)
|
if (ntype)
|
||||||
in_child = 1;
|
in_child = 1;
|
||||||
|
else
|
||||||
|
ntype = CTF_ERR;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ntype == 0)
|
if (ntype == CTF_ERR)
|
||||||
ntype = fp->ctf_ptrtab[idx];
|
{
|
||||||
|
ntype = fp->ctf_ptrtab[idx];
|
||||||
|
if (ntype == 0)
|
||||||
|
ntype = CTF_ERR;
|
||||||
|
}
|
||||||
if (ntype == CTF_ERR)
|
if (ntype == CTF_ERR)
|
||||||
goto notype;
|
goto notype;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
typedef long a_t;
|
typedef long a_t;
|
||||||
|
typedef long b_t;
|
||||||
|
|
||||||
a_t *a;
|
a_t *a;
|
||||||
|
b_t ignore2;
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
typedef long a_t;
|
typedef long a_t;
|
||||||
|
typedef long b_t;
|
||||||
|
|
||||||
a_t b;
|
a_t b;
|
||||||
|
b_t ignore1;
|
||||||
|
|
|
@ -23,13 +23,18 @@ main (int argc, char *argv[])
|
||||||
goto open_err;
|
goto open_err;
|
||||||
|
|
||||||
/* Make sure we can look up a_t * by name in all non-parent dicts, even though
|
/* Make sure we can look up a_t * by name in all non-parent dicts, even though
|
||||||
the a_t * and the type it points to are in distinct dicts. */
|
the a_t * and the type it points to are in distinct dicts; make sure we
|
||||||
|
cannot look up b_t *. */
|
||||||
|
|
||||||
while ((fp = ctf_archive_next (ctf, &i, &arcname, 1, &err)) != NULL)
|
while ((fp = ctf_archive_next (ctf, &i, &arcname, 1, &err)) != NULL)
|
||||||
{
|
{
|
||||||
if ((type = ctf_lookup_by_name (fp, "a_t *")) == CTF_ERR)
|
if ((type = ctf_lookup_by_name (fp, "a_t *")) == CTF_ERR)
|
||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
|
if ((ctf_lookup_by_name (fp, "b_t *")) != CTF_ERR ||
|
||||||
|
ctf_errno (fp) != ECTF_NOTYPE)
|
||||||
|
goto noerr;
|
||||||
|
|
||||||
if (ctf_type_reference (fp, type) == CTF_ERR)
|
if (ctf_type_reference (fp, type) == CTF_ERR)
|
||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
|
@ -51,4 +56,7 @@ main (int argc, char *argv[])
|
||||||
err:
|
err:
|
||||||
fprintf (stderr, "Lookup failed in %s: %s\n", arcname, ctf_errmsg (ctf_errno (fp)));
|
fprintf (stderr, "Lookup failed in %s: %s\n", arcname, ctf_errmsg (ctf_errno (fp)));
|
||||||
return 1;
|
return 1;
|
||||||
|
noerr:
|
||||||
|
fprintf (stderr, "Lookup unexpectedly succeeded in %s\n", arcname);
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue