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
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;
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
|
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 * 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
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 /*
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;
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 */
1966
|