diff options
author | Andy Fiddaman <omnios@citrus-it.co.uk> | 2020-11-03 18:06:23 +0000 |
---|---|---|
committer | Andy Fiddaman <omnios@citrus-it.co.uk> | 2020-11-12 21:15:20 +0000 |
commit | 3dfdac06b0c70e672dbe56a2f38ec05fc0254d07 (patch) | |
tree | 5b5b68bc9c5b7da55d542457fa81a143088e4050 | |
parent | a676209deb2ce5d0c98f331659de25e2483f8c4c (diff) | |
download | illumos-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.c | 24 | ||||
-rw-r--r-- | usr/src/common/ctf/ctf_impl.h | 1 | ||||
-rw-r--r-- | usr/src/common/ctf/ctf_types.c | 19 | ||||
-rw-r--r-- | usr/src/lib/libctf/common/ctf_dwarf.c | 17 | ||||
-rw-r--r-- | usr/src/lib/libctf/common/ctf_merge.c | 70 |
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); } } |