diff options
author | John Levon <john.levon@joyent.com> | 2020-01-29 07:27:16 -0800 |
---|---|---|
committer | John Levon <john.levon@joyent.com> | 2020-02-12 03:18:36 -0800 |
commit | fe2dc8bddec347e173d402f53feeb492640a9f98 (patch) | |
tree | dc27791c1d158d314fb5239a0b15a208bf695955 /usr/src/lib/libctf | |
parent | d5d2dbe51affdd94ab32688a7e92dd23ef5b3ba9 (diff) | |
download | illumos-joyent-fe2dc8bddec347e173d402f53feeb492640a9f98.tar.gz |
12259 CTF shouldn't assume enum size
Reviewed by: Robert Mustacchi <rm@fingolfin.org>
Approved by: Dan McDonald <danmcd@joyent.com>
Diffstat (limited to 'usr/src/lib/libctf')
-rw-r--r-- | usr/src/lib/libctf/common/ctf_dwarf.c | 45 | ||||
-rw-r--r-- | usr/src/lib/libctf/common/ctf_merge.c | 9 |
2 files changed, 44 insertions, 10 deletions
diff --git a/usr/src/lib/libctf/common/ctf_dwarf.c b/usr/src/lib/libctf/common/ctf_dwarf.c index 3f57ef6704..1aa0f2e5e1 100644 --- a/usr/src/lib/libctf/common/ctf_dwarf.c +++ b/usr/src/lib/libctf/common/ctf_dwarf.c @@ -28,7 +28,7 @@ */ /* - * Copyright 2019, Joyent, Inc. + * Copyright 2020 Joyent, Inc. */ /* @@ -1213,7 +1213,6 @@ ctf_dwarf_fixup_sou(ctf_cu_t *cup, Dwarf_Die die, ctf_id_t base, boolean_t add) int ret, kind; Dwarf_Die child, memb; Dwarf_Unsigned size; - ulong_t nsz; kind = ctf_type_kind(cup->cu_ctfp, base); VERIFY(kind != CTF_ERR); @@ -1306,8 +1305,7 @@ next: /* Finally set the size of the structure to the actual byte size */ if ((ret = ctf_dwarf_unsigned(cup, die, DW_AT_byte_size, &size)) != 0) return (ret); - nsz = size; - if ((ctf_set_size(cup->cu_ctfp, base, nsz)) == CTF_ERR) { + if ((ctf_set_size(cup->cu_ctfp, base, size)) == CTF_ERR) { int e = ctf_errno(cup->cu_ctfp); (void) snprintf(cup->cu_errbuf, cup->cu_errlen, "failed to set type size for %d to 0x%x: %s", base, @@ -1614,20 +1612,53 @@ ctf_dwarf_create_reference(ctf_cu_t *cup, Dwarf_Die die, ctf_id_t *idp, return (ctf_dwmap_add(cup, *idp, die, B_FALSE)); } +/* + * Get the size of the type of a particular die. Note that this is a simple + * version that doesn't attempt to traverse further than expecting a single + * sized type reference (so no qualifiers etc.). Nor does it attempt to do as + * much as ctf_type_size() - which we cannot use here as that doesn't look up + * dynamic types, and we don't yet want to do a ctf_update(). + */ static int -ctf_dwarf_create_enum(ctf_cu_t *cup, Dwarf_Die die, ctf_id_t *idp, int isroot) +ctf_dwarf_get_type_size(ctf_cu_t *cup, Dwarf_Die die, size_t *sizep) { + const ctf_type_t *t; + Dwarf_Die tdie; + ctf_id_t tid; int ret; - ctf_id_t id; + + if ((ret = ctf_dwarf_refdie(cup, die, DW_AT_type, &tdie)) != 0) + return (ret); + + if ((ret = ctf_dwarf_convert_type(cup, tdie, &tid, + CTF_ADD_NONROOT)) != 0) + return (ret); + + if ((t = ctf_dyn_lookup_by_id(cup->cu_ctfp, tid)) == NULL) + return (ENOENT); + + *sizep = ctf_get_ctt_size(cup->cu_ctfp, t, NULL, NULL); + return (0); +} + +static int +ctf_dwarf_create_enum(ctf_cu_t *cup, Dwarf_Die die, ctf_id_t *idp, int isroot) +{ + size_t size = 0; Dwarf_Die child; + ctf_id_t id; char *name; + int ret; if ((ret = ctf_dwarf_string(cup, die, DW_AT_name, &name)) != 0 && ret != ENOENT) return (ret); if (ret == ENOENT) name = NULL; - id = ctf_add_enum(cup->cu_ctfp, isroot, name); + + (void) ctf_dwarf_get_type_size(cup, die, &size); + + id = ctf_add_enum(cup->cu_ctfp, isroot, name, size); ctf_dprintf("added enum %s (%d)\n", name, id); if (name != NULL) ctf_free(name, strlen(name) + 1); diff --git a/usr/src/lib/libctf/common/ctf_merge.c b/usr/src/lib/libctf/common/ctf_merge.c index 578e667079..a18a2f46ef 100644 --- a/usr/src/lib/libctf/common/ctf_merge.c +++ b/usr/src/lib/libctf/common/ctf_merge.c @@ -10,7 +10,7 @@ */ /* - * Copyright 2019, Joyent, Inc. + * Copyright 2020 Joyent, Inc. */ /* @@ -340,15 +340,18 @@ ctf_merge_add_enum(ctf_merge_types_t *cmp, ctf_id_t id) const char *name; ctf_id_t enumid; ctf_merge_enum_t cme; + size_t size; tp = LCTF_INDEX_TO_TYPEPTR(cmp->cm_src, id); - name = ctf_strraw(cmp->cm_src, tp->ctt_name); if (CTF_INFO_ISROOT(tp->ctt_info) != 0) flags = CTF_ADD_ROOT; else flags = CTF_ADD_NONROOT; - enumid = ctf_add_enum(cmp->cm_out, flags, name); + name = ctf_strraw(cmp->cm_src, tp->ctt_name); + size = ctf_get_ctt_size(cmp->cm_src, tp, NULL, NULL); + + enumid = ctf_add_enum(cmp->cm_out, flags, name, size); if (enumid == CTF_ERR) return (enumid); |