Print this page
12259 CTF shouldn't assume enum size

@@ -26,11 +26,11 @@
  * Copyright 2012 Jason King.  All rights reserved.
  * Use is subject to license terms.
  */
 
 /*
- * Copyright 2019, Joyent, Inc.
+ * Copyright 2020 Joyent, Inc.
  */
 
 /*
  * CTF DWARF conversion theory.
  *

@@ -1211,11 +1211,10 @@
 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);
         VERIFY(kind == CTF_K_STRUCT || kind == CTF_K_UNION);
 

@@ -1304,12 +1303,11 @@
                 return (0);
 
         /* 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,
                     (uint32_t)size, ctf_errmsg(e));
                 return (ECTF_CONVBKERR);

@@ -1612,24 +1610,57 @@
 
         ctf_free(name, namelen);
         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);
         if (id == CTF_ERR)
                 return (ctf_errno(cup->cu_ctfp));