8 *
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
13 *
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
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 (c) 2019, 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;
1229 }
1230
1231 if (dtd == NULL) {
1232 type = ctf_add_generic(fp, flag, name, &dtd);
1233 if (type == CTF_ERR)
1234 return (CTF_ERR); /* errno is set for us */
1235 }
1236
1237 VERIFY(type != CTF_ERR);
1238 dtd->dtd_data.ctt_info = CTF_TYPE_INFO(CTF_K_UNION, flag, 0);
1239 dtd->dtd_data.ctt_size = 0;
1240
1241 /*
1242 * Always dirty in case we modified a forward.
1243 */
1244 fp->ctf_flags |= LCTF_DIRTY;
1245
1246 return (type);
1247 }
1248
1249 ctf_id_t
1250 ctf_add_enum(ctf_file_t *fp, uint_t flag, const char *name)
1251 {
1252 ctf_hash_t *hp = &fp->ctf_enums;
1253 ctf_helem_t *hep = NULL;
1254 ctf_dtdef_t *dtd = NULL;
1255 ctf_id_t type = CTF_ERR;
1256
1257 if (name != NULL)
1258 hep = ctf_hash_lookup(hp, fp, name, strlen(name));
1259
1260 if (hep != NULL && ctf_type_kind(fp, hep->h_type) == CTF_K_FORWARD) {
1261 type = hep->h_type;
1262 dtd = ctf_dtd_lookup(fp, type);
1263 if (CTF_INFO_KIND(dtd->dtd_data.ctt_info) != CTF_K_FORWARD)
1264 dtd = NULL;
1265 }
1266
1267 if (dtd == NULL) {
1268 type = ctf_add_generic(fp, flag, name, &dtd);
1269 if (type == CTF_ERR)
1270 return (CTF_ERR); /* errno is set for us */
1271 }
1272
1273 VERIFY(type != CTF_ERR);
1274 dtd->dtd_data.ctt_info = CTF_TYPE_INFO(CTF_K_ENUM, flag, 0);
1275 dtd->dtd_data.ctt_size = fp->ctf_dmodel->ctd_int;
1276
1277 /*
1278 * Always dirty in case we modified a forward.
1279 */
1280 fp->ctf_flags |= LCTF_DIRTY;
1281
1282 return (type);
1283 }
1284
1285 ctf_id_t
1286 ctf_add_forward(ctf_file_t *fp, uint_t flag, const char *name, uint_t kind)
1287 {
1288 ctf_hash_t *hp;
1289 ctf_helem_t *hep;
1290 ctf_dtdef_t *dtd;
1291 ctf_id_t type;
1292
1293 switch (kind) {
1294 case CTF_K_STRUCT:
1295 hp = &fp->ctf_structs;
1296 break;
1534 * alignment required by the new member. Finally,
1535 * convert back to bits and store the result in
1536 * dmd_offset. Technically we could do more efficient
1537 * packing if the new member is a bit-field, but we're
1538 * the "compiler" and ANSI says we can do as we choose.
1539 */
1540 off = roundup(off, NBBY) / NBBY;
1541 off = roundup(off, MAX(malign, 1));
1542 dmd->dmd_offset = off * NBBY;
1543 ssize = off + msize;
1544 } else {
1545 dmd->dmd_offset = offset;
1546 ssize = (offset + mbitsz) / NBBY;
1547 }
1548 } else {
1549 dmd->dmd_offset = 0;
1550 ssize = ctf_get_ctt_size(fp, &dtd->dtd_data, NULL, NULL);
1551 ssize = MAX(ssize, msize);
1552 }
1553
1554 if (ssize > CTF_MAX_SIZE) {
1555 dtd->dtd_data.ctt_size = CTF_LSIZE_SENT;
1556 dtd->dtd_data.ctt_lsizehi = CTF_SIZE_TO_LSIZE_HI(ssize);
1557 dtd->dtd_data.ctt_lsizelo = CTF_SIZE_TO_LSIZE_LO(ssize);
1558 } else
1559 dtd->dtd_data.ctt_size = (ushort_t)ssize;
1560
1561 dtd->dtd_data.ctt_info = CTF_TYPE_INFO(kind, root, vlen + 1);
1562 ctf_list_append(&dtd->dtd_u.dtu_members, dmd);
1563
1564 if (s != NULL)
1565 fp->ctf_dtstrlen += strlen(s) + 1;
1566
1567 ctf_ref_inc(fp, type);
1568 fp->ctf_flags |= LCTF_DIRTY;
1569 return (0);
1570 }
1571
1572 /*
1573 * This removes a type from the dynamic section. This will fail if the type is
1574 * referenced by another type. Note that the CTF ID is never reused currently by
1575 * CTF. Note that if this container is a parent container then we just outright
1576 * refuse to remove the type. There currently is no notion of searching for the
1577 * ctf_dtdef_t in parent containers. If there is, then this constraint could
1578 * become finer grained.
1579 */
1676 * following the source type's links and embedded member types. If the
1677 * destination container already contains a named type which has the same
1678 * attributes, then we succeed and return this type but no changes occur.
1679 */
1680 ctf_id_t
1681 ctf_add_type(ctf_file_t *dst_fp, ctf_file_t *src_fp, ctf_id_t src_type)
1682 {
1683 ctf_id_t dst_type = CTF_ERR;
1684 uint_t dst_kind = CTF_K_UNKNOWN;
1685
1686 const ctf_type_t *tp;
1687 const char *name;
1688 uint_t kind, flag, vlen;
1689
1690 ctf_bundle_t src, dst;
1691 ctf_encoding_t src_en, dst_en;
1692 ctf_arinfo_t src_ar, dst_ar;
1693
1694 ctf_dtdef_t *dtd;
1695 ctf_funcinfo_t ctc;
1696 ssize_t size;
1697
1698 ctf_hash_t *hp;
1699 ctf_helem_t *hep;
1700
1701 if (dst_fp == src_fp)
1702 return (src_type);
1703
1704 if (!(dst_fp->ctf_flags & LCTF_RDWR))
1705 return (ctf_set_errno(dst_fp, ECTF_RDONLY));
1706
1707 if ((tp = ctf_lookup_by_id(&src_fp, src_type)) == NULL)
1708 return (ctf_set_errno(dst_fp, ctf_errno(src_fp)));
1709
1710 name = ctf_strptr(src_fp, tp->ctt_name);
1711 kind = LCTF_INFO_KIND(src_fp, tp->ctt_info);
1712 flag = LCTF_INFO_ROOT(src_fp, tp->ctt_info);
1713 vlen = LCTF_INFO_VLEN(src_fp, tp->ctt_info);
1714
1715 switch (kind) {
1716 case CTF_K_STRUCT:
1871 return (ctf_set_errno(dst_fp, ECTF_CONFLICT));
1872
1873 break;
1874 }
1875
1876 /*
1877 * Unlike the other cases, copying structs and unions is done
1878 * manually so as to avoid repeated lookups in ctf_add_member
1879 * and to ensure the exact same member offsets as in src_type.
1880 */
1881 dst_type = ctf_add_generic(dst_fp, flag, name, &dtd);
1882 if (dst_type == CTF_ERR)
1883 return (CTF_ERR); /* errno is set for us */
1884
1885 dst.ctb_type = dst_type;
1886 dst.ctb_dtd = dtd;
1887
1888 if (ctf_member_iter(src_fp, src_type, membadd, &dst) != 0)
1889 errs++; /* increment errs and fail at bottom of case */
1890
1891 if ((size = ctf_type_size(src_fp, src_type)) > CTF_MAX_SIZE) {
1892 dtd->dtd_data.ctt_size = CTF_LSIZE_SENT;
1893 dtd->dtd_data.ctt_lsizehi = CTF_SIZE_TO_LSIZE_HI(size);
1894 dtd->dtd_data.ctt_lsizelo = CTF_SIZE_TO_LSIZE_LO(size);
1895 } else
1896 dtd->dtd_data.ctt_size = (ushort_t)size;
1897
1898 dtd->dtd_data.ctt_info = CTF_TYPE_INFO(kind, flag, vlen);
1899
1900 /*
1901 * Make a final pass through the members changing each dmd_type
1902 * (a src_fp type) to an equivalent type in dst_fp. We pass
1903 * through all members, leaving any that fail set to CTF_ERR.
1904 */
1905 for (dmd = ctf_list_next(&dtd->dtd_u.dtu_members);
1906 dmd != NULL; dmd = ctf_list_next(dmd)) {
1907 if ((dmd->dmd_type = ctf_add_type(dst_fp, src_fp,
1908 dmd->dmd_type)) == CTF_ERR)
1909 errs++;
1910 }
1911
1912 if (errs)
1913 return (CTF_ERR); /* errno is set for us */
1914
1915 /*
1916 * Now that we know that we can't fail, we go through and bump
1917 * all the reference counts on the member types.
1918 */
1919 for (dmd = ctf_list_next(&dtd->dtd_u.dtu_members);
1920 dmd != NULL; dmd = ctf_list_next(dmd))
1921 ctf_ref_inc(dst_fp, dmd->dmd_type);
1922 break;
1923 }
1924
1925 case CTF_K_ENUM:
1926 if (dst_type != CTF_ERR && dst_kind != CTF_K_FORWARD) {
1927 if (ctf_enum_iter(src_fp, src_type, enumcmp, &dst) ||
1928 ctf_enum_iter(dst_fp, dst_type, enumcmp, &src))
1929 return (ctf_set_errno(dst_fp, ECTF_CONFLICT));
1930 } else {
1931 dst_type = ctf_add_enum(dst_fp, flag, name);
1932 if ((dst.ctb_type = dst_type) == CTF_ERR ||
1933 ctf_enum_iter(src_fp, src_type, enumadd, &dst))
1934 return (CTF_ERR); /* errno is set for us */
1935 }
1936 break;
1937
1938 case CTF_K_FORWARD:
1939 if (dst_type == CTF_ERR) {
1940 dst_type = ctf_add_forward(dst_fp,
1941 flag, name, CTF_K_STRUCT); /* assume STRUCT */
1942 }
1943 break;
1944
1945 case CTF_K_TYPEDEF:
1946 src_type = ctf_type_reference(src_fp, src_type);
1947 src_type = ctf_add_type(dst_fp, src_fp, src_type);
1948
1949 if (src_type == CTF_ERR)
1950 return (CTF_ERR); /* errno is set for us */
1951
2148 uint_t kind;
2149 size_t oldsz;
2150
2151 if (!(fp->ctf_flags & LCTF_RDWR))
2152 return (ctf_set_errno(fp, ECTF_RDONLY));
2153
2154 if (dtd == NULL)
2155 return (ctf_set_errno(fp, ECTF_BADID));
2156
2157 kind = CTF_INFO_KIND(dtd->dtd_data.ctt_info);
2158
2159 if (kind != CTF_K_STRUCT && kind != CTF_K_UNION)
2160 return (ctf_set_errno(fp, ECTF_NOTSOU));
2161
2162 if ((oldsz = dtd->dtd_data.ctt_size) == CTF_LSIZE_SENT)
2163 oldsz = CTF_TYPE_LSIZE(&dtd->dtd_data);
2164
2165 if (newsz < oldsz)
2166 return (ctf_set_errno(fp, EINVAL));
2167
2168 if (newsz > CTF_MAX_SIZE) {
2169 dtd->dtd_data.ctt_size = CTF_LSIZE_SENT;
2170 dtd->dtd_data.ctt_lsizehi = CTF_SIZE_TO_LSIZE_HI(newsz);
2171 dtd->dtd_data.ctt_lsizelo = CTF_SIZE_TO_LSIZE_LO(newsz);
2172 } else {
2173 dtd->dtd_data.ctt_size = (ushort_t)newsz;
2174 }
2175
2176 fp->ctf_flags |= LCTF_DIRTY;
2177 return (0);
2178 }
2179
2180 int
2181 ctf_set_root(ctf_file_t *fp, ctf_id_t id, const boolean_t vis)
2182 {
2183 ctf_dtdef_t *dtd = ctf_dtd_lookup(fp, id);
2184 uint_t kind, vlen;
2185
2186 if (!(fp->ctf_flags & LCTF_RDWR))
2187 return (ctf_set_errno(fp, ECTF_RDONLY));
2188
2189 if (dtd == NULL)
2190 return (ctf_set_errno(fp, ECTF_BADID));
2191
2192 kind = CTF_INFO_KIND(dtd->dtd_data.ctt_info);
2193 vlen = CTF_INFO_VLEN(dtd->dtd_data.ctt_info);
2194
|
8 *
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
13 *
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
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;
1237 }
1238
1239 if (dtd == NULL) {
1240 type = ctf_add_generic(fp, flag, name, &dtd);
1241 if (type == CTF_ERR)
1242 return (CTF_ERR); /* errno is set for us */
1243 }
1244
1245 VERIFY(type != CTF_ERR);
1246 dtd->dtd_data.ctt_info = CTF_TYPE_INFO(CTF_K_UNION, flag, 0);
1247 dtd->dtd_data.ctt_size = 0;
1248
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;
1314 break;
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 */
1964
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
|