Print this page
rm code review


  18  * information: Portions Copyright [yyyy] [name of copyright owner]
  19  *
  20  * CDDL HEADER END
  21  */
  22 
  23 /*
  24  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
  25  * Use is subject to license terms.
  26  */
  27 /*
  28  * Copyright 2020 Joyent, Inc.
  29  */
  30 
  31 #include <sys/sysmacros.h>
  32 #include <sys/param.h>
  33 #include <sys/mman.h>
  34 #include <ctf_impl.h>
  35 #include <sys/debug.h>
  36 
  37 /*








  38  * This static string is used as the template for initially populating a
  39  * dynamic container's string table.  We always store \0 in the first byte,
  40  * and we use the generic string "PARENT" to mark this container's parent
  41  * if one is associated with the container using ctf_import().
  42  */
  43 static const char _CTF_STRTAB_TEMPLATE[] = "\0PARENT";
  44 
  45 /*
  46  * To create an empty CTF container, we just declare a zeroed header and call
  47  * ctf_bufopen() on it.  If ctf_bufopen succeeds, we mark the new container r/w
  48  * and initialize the dynamic members.  We set dtstrlen to 1 to reserve the
  49  * first byte of the string table for a \0 byte, and we start assigning type
  50  * IDs at 1 because type ID 0 is used as a sentinel.
  51  */
  52 ctf_file_t *
  53 ctf_create(int *errp)
  54 {
  55         static const ctf_header_t hdr = { { CTF_MAGIC, CTF_VERSION, 0 } };
  56 
  57         const ulong_t hashlen = 128;


1241         /*
1242          * Always dirty in case we modified a forward.
1243          */
1244         fp->ctf_flags |= LCTF_DIRTY;
1245 
1246         return (type);
1247 }
1248 
1249 /*
1250  * If size is 0, we use the standard integer size. This is almost always the
1251  * case, except for packed enums.
1252  */
1253 ctf_id_t
1254 ctf_add_enum(ctf_file_t *fp, uint_t flag, const char *name, size_t size)
1255 {
1256         ctf_hash_t *hp = &fp->ctf_enums;
1257         ctf_helem_t *hep = NULL;
1258         ctf_dtdef_t *dtd = NULL;
1259         ctf_id_t type = CTF_ERR;
1260 




1261         if (name != NULL)
1262                 hep = ctf_hash_lookup(hp, fp, name, strlen(name));
1263 
1264         if (hep != NULL && ctf_type_kind(fp, hep->h_type) == CTF_K_FORWARD) {
1265                 type = hep->h_type;
1266                 dtd = ctf_dtd_lookup(fp, type);
1267                 if (CTF_INFO_KIND(dtd->dtd_data.ctt_info) != CTF_K_FORWARD)
1268                         dtd = NULL;
1269         }
1270 
1271         if (dtd == NULL) {
1272                 type = ctf_add_generic(fp, flag, name, &dtd);
1273                 if (type == CTF_ERR)
1274                         return (CTF_ERR); /* errno is set for us */
1275         }
1276 
1277         VERIFY(type != CTF_ERR);
1278         dtd->dtd_data.ctt_info = CTF_TYPE_INFO(CTF_K_ENUM, flag, 0);
1279 
1280         if (size == 0) {
1281                 dtd->dtd_data.ctt_size = fp->ctf_dmodel->ctd_int;
1282         } else {
1283                 if (size > CTF_MAX_SIZE) {
1284                         dtd->dtd_data.ctt_size = CTF_LSIZE_SENT;
1285                         dtd->dtd_data.ctt_lsizehi = CTF_SIZE_TO_LSIZE_HI(size);
1286                         dtd->dtd_data.ctt_lsizelo = CTF_SIZE_TO_LSIZE_LO(size);
1287                 } else
1288                         dtd->dtd_data.ctt_size = size;
1289         }
1290 
1291         /*
1292          * Always dirty in case we modified a forward.
1293          */
1294         fp->ctf_flags |= LCTF_DIRTY;
1295 
1296         return (type);
1297 }
1298 
1299 ctf_id_t
1300 ctf_add_forward(ctf_file_t *fp, uint_t flag, const char *name, uint_t kind)
1301 {
1302         ctf_hash_t *hp;
1303         ctf_helem_t *hep;
1304         ctf_dtdef_t *dtd;
1305         ctf_id_t type;
1306 
1307         switch (kind) {
1308         case CTF_K_STRUCT:
1309                 hp = &fp->ctf_structs;


1548                          * alignment required by the new member.  Finally,
1549                          * convert back to bits and store the result in
1550                          * dmd_offset.  Technically we could do more efficient
1551                          * packing if the new member is a bit-field, but we're
1552                          * the "compiler" and ANSI says we can do as we choose.
1553                          */
1554                         off = roundup(off, NBBY) / NBBY;
1555                         off = roundup(off, MAX(malign, 1));
1556                         dmd->dmd_offset = off * NBBY;
1557                         ssize = off + msize;
1558                 } else {
1559                         dmd->dmd_offset = offset;
1560                         ssize = (offset + mbitsz) / NBBY;
1561                 }
1562         } else {
1563                 dmd->dmd_offset = 0;
1564                 ssize = ctf_get_ctt_size(fp, &dtd->dtd_data, NULL, NULL);
1565                 ssize = MAX(ssize, msize);
1566         }
1567 
1568         if (ssize > CTF_MAX_SIZE) {
1569                 dtd->dtd_data.ctt_size = CTF_LSIZE_SENT;
1570                 dtd->dtd_data.ctt_lsizehi = CTF_SIZE_TO_LSIZE_HI(ssize);
1571                 dtd->dtd_data.ctt_lsizelo = CTF_SIZE_TO_LSIZE_LO(ssize);
1572         } else
1573                 dtd->dtd_data.ctt_size = (ushort_t)ssize;
1574 
1575         dtd->dtd_data.ctt_info = CTF_TYPE_INFO(kind, root, vlen + 1);
1576         ctf_list_append(&dtd->dtd_u.dtu_members, dmd);
1577 
1578         if (s != NULL)
1579                 fp->ctf_dtstrlen += strlen(s) + 1;
1580 
1581         ctf_ref_inc(fp, type);
1582         fp->ctf_flags |= LCTF_DIRTY;
1583         return (0);
1584 }
1585 
1586 /*
1587  * This removes a type from the dynamic section. This will fail if the type is
1588  * referenced by another type. Note that the CTF ID is never reused currently by
1589  * CTF. Note that if this container is a parent container then we just outright
1590  * refuse to remove the type. There currently is no notion of searching for the
1591  * ctf_dtdef_t in parent containers. If there is, then this constraint could
1592  * become finer grained.
1593  */


1690  * following the source type's links and embedded member types.  If the
1691  * destination container already contains a named type which has the same
1692  * attributes, then we succeed and return this type but no changes occur.
1693  */
1694 ctf_id_t
1695 ctf_add_type(ctf_file_t *dst_fp, ctf_file_t *src_fp, ctf_id_t src_type)
1696 {
1697         ctf_id_t dst_type = CTF_ERR;
1698         uint_t dst_kind = CTF_K_UNKNOWN;
1699 
1700         const ctf_type_t *tp;
1701         const char *name;
1702         uint_t kind, flag, vlen;
1703 
1704         ctf_bundle_t src, dst;
1705         ctf_encoding_t src_en, dst_en;
1706         ctf_arinfo_t src_ar, dst_ar;
1707 
1708         ctf_dtdef_t *dtd;
1709         ctf_funcinfo_t ctc;
1710         ssize_t size;
1711 
1712         ctf_hash_t *hp;
1713         ctf_helem_t *hep;
1714 
1715         if (dst_fp == src_fp)
1716                 return (src_type);
1717 
1718         if (!(dst_fp->ctf_flags & LCTF_RDWR))
1719                 return (ctf_set_errno(dst_fp, ECTF_RDONLY));
1720 
1721         if ((tp = ctf_lookup_by_id(&src_fp, src_type)) == NULL)
1722                 return (ctf_set_errno(dst_fp, ctf_errno(src_fp)));
1723 
1724         name = ctf_strptr(src_fp, tp->ctt_name);
1725         kind = LCTF_INFO_KIND(src_fp, tp->ctt_info);
1726         flag = LCTF_INFO_ROOT(src_fp, tp->ctt_info);
1727         vlen = LCTF_INFO_VLEN(src_fp, tp->ctt_info);
1728 
1729         switch (kind) {
1730         case CTF_K_STRUCT:


1885                                 return (ctf_set_errno(dst_fp, ECTF_CONFLICT));
1886 
1887                         break;
1888                 }
1889 
1890                 /*
1891                  * Unlike the other cases, copying structs and unions is done
1892                  * manually so as to avoid repeated lookups in ctf_add_member
1893                  * and to ensure the exact same member offsets as in src_type.
1894                  */
1895                 dst_type = ctf_add_generic(dst_fp, flag, name, &dtd);
1896                 if (dst_type == CTF_ERR)
1897                         return (CTF_ERR); /* errno is set for us */
1898 
1899                 dst.ctb_type = dst_type;
1900                 dst.ctb_dtd = dtd;
1901 
1902                 if (ctf_member_iter(src_fp, src_type, membadd, &dst) != 0)
1903                         errs++; /* increment errs and fail at bottom of case */
1904 
1905                 if ((size = ctf_type_size(src_fp, src_type)) > CTF_MAX_SIZE) {
1906                         dtd->dtd_data.ctt_size = CTF_LSIZE_SENT;
1907                         dtd->dtd_data.ctt_lsizehi = CTF_SIZE_TO_LSIZE_HI(size);
1908                         dtd->dtd_data.ctt_lsizelo = CTF_SIZE_TO_LSIZE_LO(size);
1909                 } else
1910                         dtd->dtd_data.ctt_size = (ushort_t)size;
1911 
1912                 dtd->dtd_data.ctt_info = CTF_TYPE_INFO(kind, flag, vlen);
1913 
1914                 /*
1915                  * Make a final pass through the members changing each dmd_type
1916                  * (a src_fp type) to an equivalent type in dst_fp.  We pass
1917                  * through all members, leaving any that fail set to CTF_ERR.
1918                  */
1919                 for (dmd = ctf_list_next(&dtd->dtd_u.dtu_members);
1920                     dmd != NULL; dmd = ctf_list_next(dmd)) {
1921                         if ((dmd->dmd_type = ctf_add_type(dst_fp, src_fp,
1922                             dmd->dmd_type)) == CTF_ERR)
1923                                 errs++;
1924                 }
1925 
1926                 if (errs)
1927                         return (CTF_ERR); /* errno is set for us */
1928 
1929                 /*
1930                  * Now that we know that we can't fail, we go through and bump
1931                  * all the reference counts on the member types.
1932                  */
1933                 for (dmd = ctf_list_next(&dtd->dtd_u.dtu_members);
1934                     dmd != NULL; dmd = ctf_list_next(dmd))
1935                         ctf_ref_inc(dst_fp, dmd->dmd_type);
1936                 break;
1937         }
1938 
1939         case CTF_K_ENUM:
1940                 if (dst_type != CTF_ERR && dst_kind != CTF_K_FORWARD) {
1941                         if (ctf_enum_iter(src_fp, src_type, enumcmp, &dst) ||
1942                             ctf_enum_iter(dst_fp, dst_type, enumcmp, &src))
1943                                 return (ctf_set_errno(dst_fp, ECTF_CONFLICT));
1944                 } else {
1945                         size_t size = ctf_type_size(src_fp, src_type);




1946                         dst_type = ctf_add_enum(dst_fp, flag, name, size);
1947                         if ((dst.ctb_type = dst_type) == CTF_ERR ||
1948                             ctf_enum_iter(src_fp, src_type, enumadd, &dst))
1949                                 return (CTF_ERR); /* errno is set for us */
1950                 }
1951                 break;
1952 
1953         case CTF_K_FORWARD:
1954                 if (dst_type == CTF_ERR) {
1955                         dst_type = ctf_add_forward(dst_fp,
1956                             flag, name, CTF_K_STRUCT); /* assume STRUCT */
1957                 }
1958                 break;
1959 
1960         case CTF_K_TYPEDEF:
1961                 src_type = ctf_type_reference(src_fp, src_type);
1962                 src_type = ctf_add_type(dst_fp, src_fp, src_type);
1963 
1964                 if (src_type == CTF_ERR)
1965                         return (CTF_ERR); /* errno is set for us */


2163         uint_t kind;
2164         size_t oldsz;
2165 
2166         if (!(fp->ctf_flags & LCTF_RDWR))
2167                 return (ctf_set_errno(fp, ECTF_RDONLY));
2168 
2169         if (dtd == NULL)
2170                 return (ctf_set_errno(fp, ECTF_BADID));
2171 
2172         kind = CTF_INFO_KIND(dtd->dtd_data.ctt_info);
2173 
2174         if (kind != CTF_K_STRUCT && kind != CTF_K_UNION)
2175                 return (ctf_set_errno(fp, ECTF_NOTSOU));
2176 
2177         if ((oldsz = dtd->dtd_data.ctt_size) == CTF_LSIZE_SENT)
2178                 oldsz = CTF_TYPE_LSIZE(&dtd->dtd_data);
2179 
2180         if (newsz < oldsz)
2181                 return (ctf_set_errno(fp, EINVAL));
2182 
2183         if (newsz > CTF_MAX_SIZE) {
2184                 dtd->dtd_data.ctt_size = CTF_LSIZE_SENT;
2185                 dtd->dtd_data.ctt_lsizehi = CTF_SIZE_TO_LSIZE_HI(newsz);
2186                 dtd->dtd_data.ctt_lsizelo = CTF_SIZE_TO_LSIZE_LO(newsz);
2187         } else {
2188                 dtd->dtd_data.ctt_size = (ushort_t)newsz;
2189         }
2190 
2191         fp->ctf_flags |= LCTF_DIRTY;
2192         return (0);
2193 }
2194 
2195 int
2196 ctf_set_root(ctf_file_t *fp, ctf_id_t id, const boolean_t vis)
2197 {
2198         ctf_dtdef_t *dtd = ctf_dtd_lookup(fp, id);
2199         uint_t kind, vlen;
2200 
2201         if (!(fp->ctf_flags & LCTF_RDWR))
2202                 return (ctf_set_errno(fp, ECTF_RDONLY));
2203 
2204         if (dtd == NULL)
2205                 return (ctf_set_errno(fp, ECTF_BADID));
2206 
2207         kind = CTF_INFO_KIND(dtd->dtd_data.ctt_info);
2208         vlen = CTF_INFO_VLEN(dtd->dtd_data.ctt_info);
2209 


  18  * information: Portions Copyright [yyyy] [name of copyright owner]
  19  *
  20  * CDDL HEADER END
  21  */
  22 
  23 /*
  24  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
  25  * Use is subject to license terms.
  26  */
  27 /*
  28  * Copyright 2020 Joyent, Inc.
  29  */
  30 
  31 #include <sys/sysmacros.h>
  32 #include <sys/param.h>
  33 #include <sys/mman.h>
  34 #include <ctf_impl.h>
  35 #include <sys/debug.h>
  36 
  37 /*
  38  * SSIZE_MAX is not available in the kernel, so we define it here rather than
  39  * accidentally inject into headers where it's not wanted.
  40  */
  41 #ifndef SSIZE_MAX
  42 #define SSIZE_MAX (LONG_MAX)
  43 #endif
  44 
  45 /*
  46  * This static string is used as the template for initially populating a
  47  * dynamic container's string table.  We always store \0 in the first byte,
  48  * and we use the generic string "PARENT" to mark this container's parent
  49  * if one is associated with the container using ctf_import().
  50  */
  51 static const char _CTF_STRTAB_TEMPLATE[] = "\0PARENT";
  52 
  53 /*
  54  * To create an empty CTF container, we just declare a zeroed header and call
  55  * ctf_bufopen() on it.  If ctf_bufopen succeeds, we mark the new container r/w
  56  * and initialize the dynamic members.  We set dtstrlen to 1 to reserve the
  57  * first byte of the string table for a \0 byte, and we start assigning type
  58  * IDs at 1 because type ID 0 is used as a sentinel.
  59  */
  60 ctf_file_t *
  61 ctf_create(int *errp)
  62 {
  63         static const ctf_header_t hdr = { { CTF_MAGIC, CTF_VERSION, 0 } };
  64 
  65         const ulong_t hashlen = 128;


1249         /*
1250          * Always dirty in case we modified a forward.
1251          */
1252         fp->ctf_flags |= LCTF_DIRTY;
1253 
1254         return (type);
1255 }
1256 
1257 /*
1258  * If size is 0, we use the standard integer size. This is almost always the
1259  * case, except for packed enums.
1260  */
1261 ctf_id_t
1262 ctf_add_enum(ctf_file_t *fp, uint_t flag, const char *name, size_t size)
1263 {
1264         ctf_hash_t *hp = &fp->ctf_enums;
1265         ctf_helem_t *hep = NULL;
1266         ctf_dtdef_t *dtd = NULL;
1267         ctf_id_t type = CTF_ERR;
1268 
1269         /* Check we could return something valid in ctf_type_size. */
1270         if (size > SSIZE_MAX)
1271                 return (ctf_set_errno(fp, EINVAL));
1272 
1273         if (name != NULL)
1274                 hep = ctf_hash_lookup(hp, fp, name, strlen(name));
1275 
1276         if (hep != NULL && ctf_type_kind(fp, hep->h_type) == CTF_K_FORWARD) {
1277                 type = hep->h_type;
1278                 dtd = ctf_dtd_lookup(fp, type);
1279                 if (CTF_INFO_KIND(dtd->dtd_data.ctt_info) != CTF_K_FORWARD)
1280                         dtd = NULL;
1281         }
1282 
1283         if (dtd == NULL) {
1284                 type = ctf_add_generic(fp, flag, name, &dtd);
1285                 if (type == CTF_ERR)
1286                         return (CTF_ERR); /* errno is set for us */
1287         }
1288 
1289         VERIFY(type != CTF_ERR);
1290         dtd->dtd_data.ctt_info = CTF_TYPE_INFO(CTF_K_ENUM, flag, 0);
1291 
1292         ctf_set_ctt_size(&dtd->dtd_data, size == 0 ?
1293             fp->ctf_dmodel->ctd_int : size);








1294 
1295         /*
1296          * Always dirty in case we modified a forward.
1297          */
1298         fp->ctf_flags |= LCTF_DIRTY;
1299 
1300         return (type);
1301 }
1302 
1303 ctf_id_t
1304 ctf_add_forward(ctf_file_t *fp, uint_t flag, const char *name, uint_t kind)
1305 {
1306         ctf_hash_t *hp;
1307         ctf_helem_t *hep;
1308         ctf_dtdef_t *dtd;
1309         ctf_id_t type;
1310 
1311         switch (kind) {
1312         case CTF_K_STRUCT:
1313                 hp = &fp->ctf_structs;


1552                          * alignment required by the new member.  Finally,
1553                          * convert back to bits and store the result in
1554                          * dmd_offset.  Technically we could do more efficient
1555                          * packing if the new member is a bit-field, but we're
1556                          * the "compiler" and ANSI says we can do as we choose.
1557                          */
1558                         off = roundup(off, NBBY) / NBBY;
1559                         off = roundup(off, MAX(malign, 1));
1560                         dmd->dmd_offset = off * NBBY;
1561                         ssize = off + msize;
1562                 } else {
1563                         dmd->dmd_offset = offset;
1564                         ssize = (offset + mbitsz) / NBBY;
1565                 }
1566         } else {
1567                 dmd->dmd_offset = 0;
1568                 ssize = ctf_get_ctt_size(fp, &dtd->dtd_data, NULL, NULL);
1569                 ssize = MAX(ssize, msize);
1570         }
1571 
1572         ctf_set_ctt_size(&dtd->dtd_data, ssize);





1573 
1574         dtd->dtd_data.ctt_info = CTF_TYPE_INFO(kind, root, vlen + 1);
1575         ctf_list_append(&dtd->dtd_u.dtu_members, dmd);
1576 
1577         if (s != NULL)
1578                 fp->ctf_dtstrlen += strlen(s) + 1;
1579 
1580         ctf_ref_inc(fp, type);
1581         fp->ctf_flags |= LCTF_DIRTY;
1582         return (0);
1583 }
1584 
1585 /*
1586  * This removes a type from the dynamic section. This will fail if the type is
1587  * referenced by another type. Note that the CTF ID is never reused currently by
1588  * CTF. Note that if this container is a parent container then we just outright
1589  * refuse to remove the type. There currently is no notion of searching for the
1590  * ctf_dtdef_t in parent containers. If there is, then this constraint could
1591  * become finer grained.
1592  */


1689  * following the source type's links and embedded member types.  If the
1690  * destination container already contains a named type which has the same
1691  * attributes, then we succeed and return this type but no changes occur.
1692  */
1693 ctf_id_t
1694 ctf_add_type(ctf_file_t *dst_fp, ctf_file_t *src_fp, ctf_id_t src_type)
1695 {
1696         ctf_id_t dst_type = CTF_ERR;
1697         uint_t dst_kind = CTF_K_UNKNOWN;
1698 
1699         const ctf_type_t *tp;
1700         const char *name;
1701         uint_t kind, flag, vlen;
1702 
1703         ctf_bundle_t src, dst;
1704         ctf_encoding_t src_en, dst_en;
1705         ctf_arinfo_t src_ar, dst_ar;
1706 
1707         ctf_dtdef_t *dtd;
1708         ctf_funcinfo_t ctc;

1709 
1710         ctf_hash_t *hp;
1711         ctf_helem_t *hep;
1712 
1713         if (dst_fp == src_fp)
1714                 return (src_type);
1715 
1716         if (!(dst_fp->ctf_flags & LCTF_RDWR))
1717                 return (ctf_set_errno(dst_fp, ECTF_RDONLY));
1718 
1719         if ((tp = ctf_lookup_by_id(&src_fp, src_type)) == NULL)
1720                 return (ctf_set_errno(dst_fp, ctf_errno(src_fp)));
1721 
1722         name = ctf_strptr(src_fp, tp->ctt_name);
1723         kind = LCTF_INFO_KIND(src_fp, tp->ctt_info);
1724         flag = LCTF_INFO_ROOT(src_fp, tp->ctt_info);
1725         vlen = LCTF_INFO_VLEN(src_fp, tp->ctt_info);
1726 
1727         switch (kind) {
1728         case CTF_K_STRUCT:


1883                                 return (ctf_set_errno(dst_fp, ECTF_CONFLICT));
1884 
1885                         break;
1886                 }
1887 
1888                 /*
1889                  * Unlike the other cases, copying structs and unions is done
1890                  * manually so as to avoid repeated lookups in ctf_add_member
1891                  * and to ensure the exact same member offsets as in src_type.
1892                  */
1893                 dst_type = ctf_add_generic(dst_fp, flag, name, &dtd);
1894                 if (dst_type == CTF_ERR)
1895                         return (CTF_ERR); /* errno is set for us */
1896 
1897                 dst.ctb_type = dst_type;
1898                 dst.ctb_dtd = dtd;
1899 
1900                 if (ctf_member_iter(src_fp, src_type, membadd, &dst) != 0)
1901                         errs++; /* increment errs and fail at bottom of case */
1902 
1903                 ctf_set_ctt_size(&dtd->dtd_data,
1904                     ctf_type_size(src_fp, src_type));




1905 
1906                 dtd->dtd_data.ctt_info = CTF_TYPE_INFO(kind, flag, vlen);
1907 
1908                 /*
1909                  * Make a final pass through the members changing each dmd_type
1910                  * (a src_fp type) to an equivalent type in dst_fp.  We pass
1911                  * through all members, leaving any that fail set to CTF_ERR.
1912                  */
1913                 for (dmd = ctf_list_next(&dtd->dtd_u.dtu_members);
1914                     dmd != NULL; dmd = ctf_list_next(dmd)) {
1915                         if ((dmd->dmd_type = ctf_add_type(dst_fp, src_fp,
1916                             dmd->dmd_type)) == CTF_ERR)
1917                                 errs++;
1918                 }
1919 
1920                 if (errs)
1921                         return (CTF_ERR); /* errno is set for us */
1922 
1923                 /*
1924                  * Now that we know that we can't fail, we go through and bump
1925                  * all the reference counts on the member types.
1926                  */
1927                 for (dmd = ctf_list_next(&dtd->dtd_u.dtu_members);
1928                     dmd != NULL; dmd = ctf_list_next(dmd))
1929                         ctf_ref_inc(dst_fp, dmd->dmd_type);
1930                 break;
1931         }
1932 
1933         case CTF_K_ENUM:
1934                 if (dst_type != CTF_ERR && dst_kind != CTF_K_FORWARD) {
1935                         if (ctf_enum_iter(src_fp, src_type, enumcmp, &dst) ||
1936                             ctf_enum_iter(dst_fp, dst_type, enumcmp, &src))
1937                                 return (ctf_set_errno(dst_fp, ECTF_CONFLICT));
1938                 } else {
1939                         ssize_t size = ctf_type_size(src_fp, src_type);
1940 
1941                         if (size == CTF_ERR)
1942                                 return (CTF_ERR); /* errno is set for us */
1943 
1944                         dst_type = ctf_add_enum(dst_fp, flag, name, size);
1945                         if ((dst.ctb_type = dst_type) == CTF_ERR ||
1946                             ctf_enum_iter(src_fp, src_type, enumadd, &dst))
1947                                 return (CTF_ERR); /* errno is set for us */
1948                 }
1949                 break;
1950 
1951         case CTF_K_FORWARD:
1952                 if (dst_type == CTF_ERR) {
1953                         dst_type = ctf_add_forward(dst_fp,
1954                             flag, name, CTF_K_STRUCT); /* assume STRUCT */
1955                 }
1956                 break;
1957 
1958         case CTF_K_TYPEDEF:
1959                 src_type = ctf_type_reference(src_fp, src_type);
1960                 src_type = ctf_add_type(dst_fp, src_fp, src_type);
1961 
1962                 if (src_type == CTF_ERR)
1963                         return (CTF_ERR); /* errno is set for us */


2161         uint_t kind;
2162         size_t oldsz;
2163 
2164         if (!(fp->ctf_flags & LCTF_RDWR))
2165                 return (ctf_set_errno(fp, ECTF_RDONLY));
2166 
2167         if (dtd == NULL)
2168                 return (ctf_set_errno(fp, ECTF_BADID));
2169 
2170         kind = CTF_INFO_KIND(dtd->dtd_data.ctt_info);
2171 
2172         if (kind != CTF_K_STRUCT && kind != CTF_K_UNION)
2173                 return (ctf_set_errno(fp, ECTF_NOTSOU));
2174 
2175         if ((oldsz = dtd->dtd_data.ctt_size) == CTF_LSIZE_SENT)
2176                 oldsz = CTF_TYPE_LSIZE(&dtd->dtd_data);
2177 
2178         if (newsz < oldsz)
2179                 return (ctf_set_errno(fp, EINVAL));
2180 
2181         ctf_set_ctt_size(&dtd->dtd_data, newsz);






2182 
2183         fp->ctf_flags |= LCTF_DIRTY;
2184         return (0);
2185 }
2186 
2187 int
2188 ctf_set_root(ctf_file_t *fp, ctf_id_t id, const boolean_t vis)
2189 {
2190         ctf_dtdef_t *dtd = ctf_dtd_lookup(fp, id);
2191         uint_t kind, vlen;
2192 
2193         if (!(fp->ctf_flags & LCTF_RDWR))
2194                 return (ctf_set_errno(fp, ECTF_RDONLY));
2195 
2196         if (dtd == NULL)
2197                 return (ctf_set_errno(fp, ECTF_BADID));
2198 
2199         kind = CTF_INFO_KIND(dtd->dtd_data.ctt_info);
2200         vlen = CTF_INFO_VLEN(dtd->dtd_data.ctt_info);
2201