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
|