summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndy Fiddaman <omnios@citrus-it.co.uk>2020-11-03 18:06:23 +0000
committerAndy Fiddaman <omnios@citrus-it.co.uk>2020-11-12 21:15:20 +0000
commit3dfdac06b0c70e672dbe56a2f38ec05fc0254d07 (patch)
tree5b5b68bc9c5b7da55d542457fa81a143088e4050
parenta676209deb2ce5d0c98f331659de25e2483f8c4c (diff)
downloadillumos-joyent-3dfdac06b0c70e672dbe56a2f38ec05fc0254d07.tar.gz
13278 CTF assertion failed cmp->cm_tmap[id].cmt_map == suid
Reviewed by: Robert Mustacchi <rm@fingolfin.org> Approved by: Dan McDonald <danmcd@joyent.com>
-rw-r--r--usr/src/common/ctf/ctf_hash.c24
-rw-r--r--usr/src/common/ctf/ctf_impl.h1
-rw-r--r--usr/src/common/ctf/ctf_types.c19
-rw-r--r--usr/src/lib/libctf/common/ctf_dwarf.c17
-rw-r--r--usr/src/lib/libctf/common/ctf_merge.c70
5 files changed, 104 insertions, 27 deletions
diff --git a/usr/src/common/ctf/ctf_hash.c b/usr/src/common/ctf/ctf_hash.c
index 0c5a71a5ac..f97115a791 100644
--- a/usr/src/common/ctf/ctf_hash.c
+++ b/usr/src/common/ctf/ctf_hash.c
@@ -23,6 +23,8 @@
/*
* Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
+ *
+ * Copyright 2020 OmniOS Community Edition (OmniOSce) Association.
*/
#include <ctf_impl.h>
@@ -175,3 +177,25 @@ ctf_hash_destroy(ctf_hash_t *hp)
hp->h_chains = NULL;
}
}
+
+void
+ctf_hash_dump(const char *tag, ctf_hash_t *hp, ctf_file_t *fp)
+{
+ ctf_dprintf("---------------\nHash dump - %s\n", tag);
+
+ for (ushort_t h = 0; h < hp->h_nbuckets; h++) {
+ ctf_helem_t *hep;
+
+ for (ushort_t i = hp->h_buckets[h]; i != 0; i = hep->h_next) {
+ ctf_strs_t *ctsp;
+ const char *str;
+
+ hep = &hp->h_chains[i];
+ ctsp = &fp->ctf_str[CTF_NAME_STID(hep->h_name)];
+ str = ctsp->cts_strs + CTF_NAME_OFFSET(hep->h_name);
+
+ ctf_dprintf(" - %3u/%3u - '%s' type %u\n", h, i, str,
+ hep->h_type);
+ }
+ }
+}
diff --git a/usr/src/common/ctf/ctf_impl.h b/usr/src/common/ctf/ctf_impl.h
index d4ab96c4de..b208cfb486 100644
--- a/usr/src/common/ctf/ctf_impl.h
+++ b/usr/src/common/ctf/ctf_impl.h
@@ -273,6 +273,7 @@ extern ctf_helem_t *ctf_hash_lookup(ctf_hash_t *, ctf_file_t *,
const char *, size_t);
extern uint_t ctf_hash_size(const ctf_hash_t *);
extern void ctf_hash_destroy(ctf_hash_t *);
+extern void ctf_hash_dump(const char *, ctf_hash_t *, ctf_file_t *);
#define ctf_list_prev(elem) ((void *)(((ctf_list_t *)(elem))->l_prev))
#define ctf_list_next(elem) ((void *)(((ctf_list_t *)(elem))->l_next))
diff --git a/usr/src/common/ctf/ctf_types.c b/usr/src/common/ctf/ctf_types.c
index 6456f8a042..1fad60ddd4 100644
--- a/usr/src/common/ctf/ctf_types.c
+++ b/usr/src/common/ctf/ctf_types.c
@@ -26,6 +26,7 @@
*/
/*
* Copyright 2020 Joyent, Inc.
+ * Copyright 2020 OmniOS Community Edition (OmniOSce) Association.
*/
#include <ctf_impl.h>
@@ -369,8 +370,24 @@ ctf_type_qlname(ctf_file_t *fp, ctf_id_t type, char *buf, size_t len,
cdp->cd_type, want_func_args);
vname = NULL;
break;
- case CTF_K_STRUCT:
case CTF_K_FORWARD:
+ switch (tp->ctt_type) {
+ case CTF_K_UNION:
+ ctf_decl_sprintf(&cd, "union ");
+ break;
+ case CTF_K_ENUM:
+ ctf_decl_sprintf(&cd, "enum ");
+ break;
+ case CTF_K_STRUCT:
+ default:
+ ctf_decl_sprintf(&cd, "struct ");
+ break;
+ }
+ if (qname != NULL)
+ ctf_decl_sprintf(&cd, "%s`", qname);
+ ctf_decl_sprintf(&cd, "%s", name);
+ break;
+ case CTF_K_STRUCT:
ctf_decl_sprintf(&cd, "struct ");
if (qname != NULL)
ctf_decl_sprintf(&cd, "%s`", qname);
diff --git a/usr/src/lib/libctf/common/ctf_dwarf.c b/usr/src/lib/libctf/common/ctf_dwarf.c
index 8163b145e4..d91888d6c1 100644
--- a/usr/src/lib/libctf/common/ctf_dwarf.c
+++ b/usr/src/lib/libctf/common/ctf_dwarf.c
@@ -1507,14 +1507,15 @@ ctf_dwarf_create_sou(ctf_cu_t *cup, Dwarf_Die die, ctf_id_t *idp,
decl = 0;
}
- if (decl != 0) {
+ if (decl == B_TRUE) {
base = ctf_add_forward(cup->cu_ctfp, isroot, name, kind);
} else if (kind == CTF_K_STRUCT) {
base = ctf_add_struct(cup->cu_ctfp, isroot, name);
} else {
base = ctf_add_union(cup->cu_ctfp, isroot, name);
}
- ctf_dprintf("added sou %s (%d) (%d)\n", name, kind, base);
+ ctf_dprintf("added sou %s (%d) (%ld) forward=%d\n",
+ name, kind, base, decl == B_TRUE);
if (name != NULL)
ctf_free(name, strlen(name) + 1);
if (base == CTF_ERR)
@@ -2952,7 +2953,7 @@ ctf_dwarf_convert_one(void *arg, void *unused)
}
ret = ctf_dwarf_fixup_die(cup, B_FALSE);
- ctf_dprintf("ctf_dwarf_fixup_die (%s) returned %d\n", name,
+ ctf_dprintf("ctf_dwarf_fixup_die (%s, FALSE) returned %d\n", name,
ret);
if (ret != 0)
return (ret);
@@ -2963,7 +2964,7 @@ ctf_dwarf_convert_one(void *arg, void *unused)
}
ret = ctf_dwarf_fixup_die(cup, B_TRUE);
- ctf_dprintf("ctf_dwarf_fixup_die (%s) returned %d\n", name,
+ ctf_dprintf("ctf_dwarf_fixup_die (%s, TRUE) returned %d\n", name,
ret);
if (ret != 0)
return (ret);
@@ -2974,6 +2975,8 @@ ctf_dwarf_convert_one(void *arg, void *unused)
}
if ((ret = ctf_dwarf_conv_funcvars(cup)) != 0) {
+ ctf_dprintf("ctf_dwarf_conv_funcvars (%s) returned %d\n",
+ name, ret);
return (ctf_dwarf_error(cup, NULL, ret,
"failed to convert strong functions and variables"));
}
@@ -2985,6 +2988,8 @@ ctf_dwarf_convert_one(void *arg, void *unused)
if (cup->cu_doweaks == B_TRUE) {
if ((ret = ctf_dwarf_conv_weaks(cup)) != 0) {
+ ctf_dprintf("ctf_dwarf_conv_weaks (%s) returned %d\n",
+ name, ret);
return (ctf_dwarf_error(cup, NULL, ret,
"failed to convert weak functions and variables"));
}
@@ -3408,6 +3413,8 @@ ctf_dwarf_convert_batch(uint_t start, uint_t end, int fd, uint_t nthrs,
goto out;
}
+ ctf_dprintf("Running conversion phase\n");
+
/* Run the conversions */
ret = workq_work(wqp, ctf_dwarf_convert_one, NULL, &err);
if (ret == WORKQ_ERROR) {
@@ -3419,6 +3426,8 @@ ctf_dwarf_convert_batch(uint_t start, uint_t end, int fd, uint_t nthrs,
goto out;
}
+ ctf_dprintf("starting merge phase\n");
+
ctf_merge_t *cmp = ctf_merge_init(fd, &err);
if (cmp == NULL)
goto out;
diff --git a/usr/src/lib/libctf/common/ctf_merge.c b/usr/src/lib/libctf/common/ctf_merge.c
index a18a2f46ef..a5888de8c0 100644
--- a/usr/src/lib/libctf/common/ctf_merge.c
+++ b/usr/src/lib/libctf/common/ctf_merge.c
@@ -129,10 +129,11 @@ ctf_merge_diffcb(ctf_file_t *ifp, ctf_id_t iid, boolean_t same, ctf_file_t *ofp,
{
ctf_merge_types_t *cmp = arg;
ctf_merge_tinfo_t *cmt = cmp->cm_tmap;
+ uint_t kind;
if (same == B_TRUE) {
if (ctf_type_kind(ifp, iid) == CTF_K_FORWARD &&
- ctf_type_kind(ofp, oid) != CTF_K_FORWARD) {
+ (kind = ctf_type_kind(ofp, oid)) != CTF_K_FORWARD) {
VERIFY(cmt[oid].cmt_map == 0);
/*
@@ -153,8 +154,8 @@ ctf_merge_diffcb(ctf_file_t *ifp, ctf_id_t iid, boolean_t same, ctf_file_t *ofp,
cmt[oid].cmt_map = iid;
cmt[oid].cmt_forward = B_TRUE;
- ctf_dprintf("merge diff forward mapped %d->%d\n", oid,
- iid);
+ ctf_dprintf("merge diff forward mapped %ld->%ld (%u)\n",
+ oid, iid, kind);
return;
}
@@ -421,7 +422,7 @@ ctf_merge_add_func(ctf_merge_types_t *cmp, ctf_id_t id)
}
static int
-ctf_merge_add_forward(ctf_merge_types_t *cmp, ctf_id_t id)
+ctf_merge_add_forward(ctf_merge_types_t *cmp, ctf_id_t id, uint_t kind)
{
int ret, flags;
const ctf_type_t *tp;
@@ -434,14 +435,7 @@ ctf_merge_add_forward(ctf_merge_types_t *cmp, ctf_id_t id)
else
flags = CTF_ADD_NONROOT;
- /*
- * ctf_add_forward tries to check to see if a given forward already
- * exists in one of its hash tables. If we're here then we know that we
- * have a forward in a container that isn't present in another.
- * Therefore, we choose a token hash table to satisfy the API choice
- * here.
- */
- ret = ctf_add_forward(cmp->cm_out, flags, name, CTF_K_STRUCT);
+ ret = ctf_add_forward(cmp->cm_out, flags, name, kind);
if (ret == CTF_ERR)
return (CTF_ERR);
@@ -494,19 +488,32 @@ ctf_merge_add_sou(ctf_merge_types_t *cmp, ctf_id_t id, boolean_t forward)
else
suid = ctf_add_union(cmp->cm_out, flags, name);
+ ctf_dprintf("added sou \"%s\" as (%d) %d->%d\n", name, kind, id, suid);
+
if (suid == CTF_ERR)
return (suid);
- /*
- * If this is a forward reference then its mapping should already
- * exist.
- */
if (forward == B_FALSE) {
VERIFY(cmp->cm_tmap[id].cmt_map == 0);
cmp->cm_tmap[id].cmt_map = suid;
- ctf_dprintf("added sou \"%s\" as (%d) %d->%d\n", name, kind, id,
- suid);
} else {
+ /*
+ * If this is a forward reference then its mapping should
+ * already exist.
+ */
+ if (cmp->cm_tmap[id].cmt_map != suid) {
+ ctf_dprintf(
+ "mismatch sou \"%s\" as (%d) %d->%d (exp %d)\n",
+ name, kind, id, suid, cmp->cm_tmap[id].cmt_map);
+ ctf_hash_dump("src structs",
+ &cmp->cm_src->ctf_structs, cmp->cm_src);
+ ctf_hash_dump("src unions",
+ &cmp->cm_src->ctf_unions, cmp->cm_src);
+ ctf_hash_dump("out structs",
+ &cmp->cm_out->ctf_structs, cmp->cm_out);
+ ctf_hash_dump("out unions",
+ &cmp->cm_out->ctf_unions, cmp->cm_out);
+ }
VERIFY(cmp->cm_tmap[id].cmt_map == suid);
}
cmp->cm_tmap[id].cmt_fixup = B_TRUE;
@@ -551,9 +558,27 @@ ctf_merge_add_type(ctf_merge_types_t *cmp, ctf_id_t id)
case CTF_K_FUNCTION:
ret = ctf_merge_add_func(cmp, id);
break;
- case CTF_K_FORWARD:
- ret = ctf_merge_add_forward(cmp, id);
+ case CTF_K_FORWARD: {
+ const ctf_type_t *tp;
+ uint_t kind;
+
+ tp = LCTF_INDEX_TO_TYPEPTR(cmp->cm_src, id);
+
+ /*
+ * For forward declarations, ctt_type is the CTF_K_*
+ * kind for the tag. Older versions of the CTF tools may
+ * not have filled this in so if ctt_type is unknown or
+ * invalid, treat it as a struct. This mirrors the logic in
+ * ctf_bufopen().
+ */
+
+ kind = tp->ctt_type;
+ if (kind == CTF_K_UNKNOWN || kind >= CTF_K_MAX)
+ kind = CTF_K_STRUCT;
+
+ ret = ctf_merge_add_forward(cmp, id, kind);
break;
+ }
case CTF_K_STRUCT:
case CTF_K_UNION:
ret = ctf_merge_add_sou(cmp, id, B_FALSE);
@@ -690,6 +715,7 @@ ctf_merge_common(ctf_merge_types_t *cmp)
/* Pass 1 */
for (i = 1; i <= cmp->cm_src->ctf_typemax; i++) {
if (cmp->cm_tmap[i].cmt_forward == B_TRUE) {
+ ctf_dprintf("Forward %d\n", i);
ret = ctf_merge_add_sou(cmp, i, B_TRUE);
if (ret != 0) {
return (ret);
@@ -1566,11 +1592,11 @@ ctf_dedup_cb(ctf_file_t *ifp, ctf_id_t iid, boolean_t same, ctf_file_t *ofp,
while (cmt[oid].cmt_missing == B_FALSE)
oid = cmt[oid].cmt_map;
cmt[iid].cmt_map = oid;
- ctf_dprintf("%d->%d \n", iid, oid);
+ ctf_dprintf("dedup %d->%d \n", iid, oid);
} else {
VERIFY(cmt[iid].cmt_map == 0);
cmt[iid].cmt_missing = B_TRUE;
- ctf_dprintf("%d is missing\n", iid);
+ ctf_dprintf("dedup %d is missing\n", iid);
}
}