From: Nick Alcock Date: Tue, 19 Jan 2021 12:45:18 +0000 (+0000) Subject: libctf: lookup_by_name: do not return success for nonexistent pointer types X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=e05a3e5a491a8ef2079eef558bbe8e9feb0b3c03;p=binutils-gdb.git 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 * 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. --- diff --git a/libctf/ChangeLog b/libctf/ChangeLog index aa021fa808d..b48cc050406 100644 --- a/libctf/ChangeLog +++ b/libctf/ChangeLog @@ -1,3 +1,9 @@ +2021-01-19 Nick Alcock + + * 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 * Makefile.in: Regenerate. diff --git a/libctf/ctf-lookup.c b/libctf/ctf-lookup.c index c7f7e297822..6d4e085838c 100644 --- a/libctf/ctf-lookup.c +++ b/libctf/ctf-lookup.c @@ -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. 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 - 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); int in_child = 0; - ntype = type; + ntype = CTF_ERR; if (child && idx <= child->ctf_pptrtab_len) { ntype = child->ctf_pptrtab[idx]; if (ntype) in_child = 1; + else + ntype = CTF_ERR; } - if (ntype == 0) - ntype = fp->ctf_ptrtab[idx]; + if (ntype == CTF_ERR) + { + ntype = fp->ctf_ptrtab[idx]; + if (ntype == 0) + ntype = CTF_ERR; + } /* Try resolving to its base type and check again. */ - if (ntype == 0) + if (ntype == CTF_ERR) { if (child) 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); - ntype = 0; + ntype = CTF_ERR; if (child && idx <= child->ctf_pptrtab_len) { ntype = child->ctf_pptrtab[idx]; if (ntype) in_child = 1; + else + ntype = CTF_ERR; } - if (ntype == 0) - ntype = fp->ctf_ptrtab[idx]; + if (ntype == CTF_ERR) + { + ntype = fp->ctf_ptrtab[idx]; + if (ntype == 0) + ntype = CTF_ERR; + } if (ntype == CTF_ERR) goto notype; } diff --git a/libctf/testsuite/libctf-regression/pptrtab-a.c b/libctf/testsuite/libctf-regression/pptrtab-a.c index e9f656a0bc8..65414877114 100644 --- a/libctf/testsuite/libctf-regression/pptrtab-a.c +++ b/libctf/testsuite/libctf-regression/pptrtab-a.c @@ -1,3 +1,5 @@ typedef long a_t; +typedef long b_t; a_t *a; +b_t ignore2; diff --git a/libctf/testsuite/libctf-regression/pptrtab-b.c b/libctf/testsuite/libctf-regression/pptrtab-b.c index 6142f194c19..e458021efb1 100644 --- a/libctf/testsuite/libctf-regression/pptrtab-b.c +++ b/libctf/testsuite/libctf-regression/pptrtab-b.c @@ -1,4 +1,5 @@ typedef long a_t; +typedef long b_t; a_t b; - +b_t ignore1; diff --git a/libctf/testsuite/libctf-regression/pptrtab.c b/libctf/testsuite/libctf-regression/pptrtab.c index 5d3c2f2ee93..fe1b8fe2b43 100644 --- a/libctf/testsuite/libctf-regression/pptrtab.c +++ b/libctf/testsuite/libctf-regression/pptrtab.c @@ -23,13 +23,18 @@ main (int argc, char *argv[]) goto open_err; /* 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) { if ((type = ctf_lookup_by_name (fp, "a_t *")) == CTF_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) goto err; @@ -51,4 +56,7 @@ main (int argc, char *argv[]) err: fprintf (stderr, "Lookup failed in %s: %s\n", arcname, ctf_errmsg (ctf_errno (fp))); return 1; + noerr: + fprintf (stderr, "Lookup unexpectedly succeeded in %s\n", arcname); + return 1; }