aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNick Alcock <nick.alcock@oracle.com>2021-01-19 12:45:18 +0000
committerNick Alcock <nick.alcock@oracle.com>2021-01-19 15:23:16 +0000
commitb7540e2b88b882d6e1b01db8f9de5c78c214d99f (patch)
treea3f7dd068915487c7ae33ae769fa422d1068231c
parent[GOLD] powerpc assertion failure (diff)
downloadbinutils-gdb-b7540e2b88b882d6e1b01db8f9de5c78c214d99f.tar.gz
binutils-gdb-b7540e2b88b882d6e1b01db8f9de5c78c214d99f.tar.bz2
binutils-gdb-b7540e2b88b882d6e1b01db8f9de5c78c214d99f.zip
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. (cherry picked from commit e05a3e5a491a8ef2079eef558bbe8e9feb0b3c03)
-rw-r--r--libctf/ChangeLog6
-rw-r--r--libctf/ctf-lookup.c34
-rw-r--r--libctf/testsuite/libctf-regression/pptrtab-a.c2
-rw-r--r--libctf/testsuite/libctf-regression/pptrtab-b.c3
-rw-r--r--libctf/testsuite/libctf-regression/pptrtab.c10
5 files changed, 45 insertions, 10 deletions
diff --git a/libctf/ChangeLog b/libctf/ChangeLog
index 9a3f79cf09e..31505332465 100644
--- a/libctf/ChangeLog
+++ b/libctf/ChangeLog
@@ -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-09 Nick Clifton <nickc@redhat.com>
* 2.36 release branch crated.
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;
}