Print this page
12259 CTF shouldn't assume enum size

@@ -23,11 +23,11 @@
 /*
  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 /*
- * Copyright (c) 2019, Joyent, Inc.
+ * Copyright 2020 Joyent, Inc.
  */
 
 #include <sys/sysmacros.h>
 #include <sys/param.h>
 #include <sys/mman.h>

@@ -1244,12 +1244,16 @@
         fp->ctf_flags |= LCTF_DIRTY;
 
         return (type);
 }
 
+/*
+ * If size is 0, we use the standard integer size. This is almost always the
+ * case, except for packed enums.
+ */
 ctf_id_t
-ctf_add_enum(ctf_file_t *fp, uint_t flag, const char *name)
+ctf_add_enum(ctf_file_t *fp, uint_t flag, const char *name, size_t size)
 {
         ctf_hash_t *hp = &fp->ctf_enums;
         ctf_helem_t *hep = NULL;
         ctf_dtdef_t *dtd = NULL;
         ctf_id_t type = CTF_ERR;

@@ -1270,11 +1274,21 @@
                         return (CTF_ERR); /* errno is set for us */
         }
 
         VERIFY(type != CTF_ERR);
         dtd->dtd_data.ctt_info = CTF_TYPE_INFO(CTF_K_ENUM, flag, 0);
+
+        if (size == 0) {
         dtd->dtd_data.ctt_size = fp->ctf_dmodel->ctd_int;
+        } else {
+                if (size > CTF_MAX_SIZE) {
+                        dtd->dtd_data.ctt_size = CTF_LSIZE_SENT;
+                        dtd->dtd_data.ctt_lsizehi = CTF_SIZE_TO_LSIZE_HI(size);
+                        dtd->dtd_data.ctt_lsizelo = CTF_SIZE_TO_LSIZE_LO(size);
+                } else
+                        dtd->dtd_data.ctt_size = size;
+        }
 
         /*
          * Always dirty in case we modified a forward.
          */
         fp->ctf_flags |= LCTF_DIRTY;

@@ -1926,11 +1940,12 @@
                 if (dst_type != CTF_ERR && dst_kind != CTF_K_FORWARD) {
                         if (ctf_enum_iter(src_fp, src_type, enumcmp, &dst) ||
                             ctf_enum_iter(dst_fp, dst_type, enumcmp, &src))
                                 return (ctf_set_errno(dst_fp, ECTF_CONFLICT));
                 } else {
-                        dst_type = ctf_add_enum(dst_fp, flag, name);
+                        size_t size = ctf_type_size(src_fp, src_type);
+                        dst_type = ctf_add_enum(dst_fp, flag, name, size);
                         if ((dst.ctb_type = dst_type) == CTF_ERR ||
                             ctf_enum_iter(src_fp, src_type, enumadd, &dst))
                                 return (CTF_ERR); /* errno is set for us */
                 }
                 break;