1 1.1 darran /* 2 1.1 darran * CDDL HEADER START 3 1.1 darran * 4 1.1 darran * The contents of this file are subject to the terms of the 5 1.1 darran * Common Development and Distribution License, Version 1.0 only 6 1.1 darran * (the "License"). You may not use this file except in compliance 7 1.1 darran * with the License. 8 1.1 darran * 9 1.1 darran * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 1.1 darran * or http://www.opensolaris.org/os/licensing. 11 1.1 darran * See the License for the specific language governing permissions 12 1.1 darran * and limitations under the License. 13 1.1 darran * 14 1.1 darran * When distributing Covered Code, include this CDDL HEADER in each 15 1.1 darran * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 1.1 darran * If applicable, add the following below this CDDL HEADER, with the 17 1.1 darran * fields enclosed by brackets "[]" replaced with your own identifying 18 1.1 darran * information: Portions Copyright [yyyy] [name of copyright owner] 19 1.1 darran * 20 1.1 darran * CDDL HEADER END 21 1.1 darran */ 22 1.5 christos #ifdef HAVE_NBTOOL_CONFIG_H 23 1.5 christos #include "nbtool_config.h" 24 1.5 christos #endif 25 1.1 darran 26 1.1 darran /* 27 1.1 darran * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 28 1.1 darran * Use is subject to license terms. 29 1.1 darran */ 30 1.4 christos /* 31 1.4 christos * Copyright (c) 2013, Joyent, Inc. All rights reserved. 32 1.4 christos */ 33 1.1 darran 34 1.1 darran #include <sys/sysmacros.h> 35 1.1 darran #include <sys/param.h> 36 1.1 darran #include <sys/mman.h> 37 1.1 darran #include <ctf_impl.h> 38 1.4 christos #include <sys/debug.h> 39 1.1 darran 40 1.1 darran /* 41 1.1 darran * This static string is used as the template for initially populating a 42 1.1 darran * dynamic container's string table. We always store \0 in the first byte, 43 1.1 darran * and we use the generic string "PARENT" to mark this container's parent 44 1.1 darran * if one is associated with the container using ctf_import(). 45 1.1 darran */ 46 1.1 darran static const char _CTF_STRTAB_TEMPLATE[] = "\0PARENT"; 47 1.1 darran 48 1.1 darran /* 49 1.1 darran * To create an empty CTF container, we just declare a zeroed header and call 50 1.1 darran * ctf_bufopen() on it. If ctf_bufopen succeeds, we mark the new container r/w 51 1.1 darran * and initialize the dynamic members. We set dtstrlen to 1 to reserve the 52 1.1 darran * first byte of the string table for a \0 byte, and we start assigning type 53 1.1 darran * IDs at 1 because type ID 0 is used as a sentinel. 54 1.1 darran */ 55 1.1 darran ctf_file_t * 56 1.1 darran ctf_create(int *errp) 57 1.1 darran { 58 1.3 christos static const ctf_header_t hdr = { .cth_preamble = { 59 1.3 christos .ctp_magic = CTF_MAGIC, 60 1.3 christos .ctp_version = CTF_VERSION, 61 1.3 christos .ctp_flags = 0 62 1.3 christos } }; 63 1.1 darran 64 1.1 darran const ulong_t hashlen = 128; 65 1.1 darran ctf_dtdef_t **hash = ctf_alloc(hashlen * sizeof (ctf_dtdef_t *)); 66 1.1 darran ctf_sect_t cts; 67 1.1 darran ctf_file_t *fp; 68 1.1 darran 69 1.1 darran if (hash == NULL) 70 1.1 darran return (ctf_set_open_errno(errp, EAGAIN)); 71 1.1 darran 72 1.3 christos cts.cts_name = __UNCONST(_CTF_SECTION); 73 1.1 darran cts.cts_type = SHT_PROGBITS; 74 1.1 darran cts.cts_flags = 0; 75 1.3 christos cts.cts_data = __UNCONST(&hdr); 76 1.1 darran cts.cts_size = sizeof (hdr); 77 1.1 darran cts.cts_entsize = 1; 78 1.1 darran cts.cts_offset = 0; 79 1.1 darran 80 1.1 darran if ((fp = ctf_bufopen(&cts, NULL, NULL, errp)) == NULL) { 81 1.1 darran ctf_free(hash, hashlen * sizeof (ctf_dtdef_t *)); 82 1.1 darran return (NULL); 83 1.1 darran } 84 1.1 darran 85 1.1 darran fp->ctf_flags |= LCTF_RDWR; 86 1.1 darran fp->ctf_dthashlen = hashlen; 87 1.8 christos memset(hash, 0, hashlen * sizeof (ctf_dtdef_t *)); 88 1.1 darran fp->ctf_dthash = hash; 89 1.1 darran fp->ctf_dtstrlen = sizeof (_CTF_STRTAB_TEMPLATE); 90 1.1 darran fp->ctf_dtnextid = 1; 91 1.1 darran fp->ctf_dtoldid = 0; 92 1.1 darran 93 1.1 darran return (fp); 94 1.1 darran } 95 1.1 darran 96 1.1 darran static uchar_t * 97 1.8 christos ctf_copy_smembers(const ctf_file_t *fp, ctf_dtdef_t *dtd, uint_t soff, 98 1.8 christos uchar_t *t) 99 1.1 darran { 100 1.1 darran ctf_dmdef_t *dmd = ctf_list_next(&dtd->dtd_u.dtu_members); 101 1.8 christos size_t sz; 102 1.8 christos uint_t name; 103 1.1 darran 104 1.1 darran for (; dmd != NULL; dmd = ctf_list_next(dmd)) { 105 1.1 darran if (dmd->dmd_name) { 106 1.8 christos name = soff; 107 1.1 darran soff += strlen(dmd->dmd_name) + 1; 108 1.1 darran } else 109 1.8 christos name = 0; 110 1.1 darran 111 1.8 christos if (fp->ctf_version == CTF_VERSION_2) { 112 1.8 christos struct ctf_member_v2 ctm; 113 1.1 darran 114 1.8 christos ctm.ctm_name = name; 115 1.8 christos ctm.ctm_type = (ushort_t)dmd->dmd_type; 116 1.8 christos ctm.ctm_offset = (ushort_t)dmd->dmd_offset; 117 1.8 christos 118 1.8 christos sz = sizeof (ctm); 119 1.8 christos memcpy(t, &ctm, sz); 120 1.8 christos t += sz; 121 1.8 christos } else { 122 1.8 christos struct ctf_member_v3 ctm; 123 1.8 christos 124 1.8 christos ctm.ctm_name = name; 125 1.8 christos ctm.ctm_type = dmd->dmd_type; 126 1.8 christos ctm.ctm_offset = dmd->dmd_offset; 127 1.8 christos 128 1.8 christos sz = sizeof (ctm); 129 1.8 christos memcpy(t, &ctm, sz); 130 1.8 christos t += sz; 131 1.8 christos } 132 1.1 darran } 133 1.1 darran 134 1.1 darran return (t); 135 1.1 darran } 136 1.1 darran 137 1.1 darran static uchar_t * 138 1.8 christos ctf_copy_lmembers(const ctf_file_t *fp, ctf_dtdef_t *dtd, uint_t soff, 139 1.8 christos uchar_t *t) 140 1.1 darran { 141 1.1 darran ctf_dmdef_t *dmd = ctf_list_next(&dtd->dtd_u.dtu_members); 142 1.8 christos size_t sz; 143 1.8 christos uint_t name; 144 1.1 darran 145 1.1 darran for (; dmd != NULL; dmd = ctf_list_next(dmd)) { 146 1.1 darran if (dmd->dmd_name) { 147 1.8 christos name = soff; 148 1.1 darran soff += strlen(dmd->dmd_name) + 1; 149 1.1 darran } else 150 1.8 christos name = 0; 151 1.8 christos 152 1.8 christos if (fp->ctf_version == CTF_VERSION_2) { 153 1.8 christos struct ctf_lmember_v2 ctlm; 154 1.1 darran 155 1.8 christos ctlm.ctlm_name = name; 156 1.8 christos ctlm.ctlm_type = (ushort_t)dmd->dmd_type; 157 1.8 christos ctlm.ctlm_pad = 0; 158 1.8 christos ctlm.ctlm_offsethi = CTF_OFFSET_TO_LMEMHI(dmd->dmd_offset); 159 1.8 christos ctlm.ctlm_offsetlo = CTF_OFFSET_TO_LMEMLO(dmd->dmd_offset); 160 1.8 christos 161 1.8 christos sz = sizeof (ctlm); 162 1.8 christos memcpy(t, &ctlm, sz); 163 1.8 christos t += sz; 164 1.8 christos } else { 165 1.8 christos struct ctf_lmember_v3 ctlm; 166 1.8 christos 167 1.8 christos ctlm.ctlm_name = name; 168 1.8 christos ctlm.ctlm_type = dmd->dmd_type; 169 1.8 christos ctlm.ctlm_offsethi = CTF_OFFSET_TO_LMEMHI(dmd->dmd_offset); 170 1.8 christos ctlm.ctlm_offsetlo = CTF_OFFSET_TO_LMEMLO(dmd->dmd_offset); 171 1.8 christos 172 1.8 christos sz = sizeof (ctlm); 173 1.8 christos memcpy(t, &ctlm, sz); 174 1.8 christos t += sz; 175 1.8 christos } 176 1.1 darran 177 1.1 darran } 178 1.1 darran 179 1.1 darran return (t); 180 1.1 darran } 181 1.1 darran 182 1.1 darran static uchar_t * 183 1.1 darran ctf_copy_emembers(ctf_dtdef_t *dtd, uint_t soff, uchar_t *t) 184 1.1 darran { 185 1.1 darran ctf_dmdef_t *dmd = ctf_list_next(&dtd->dtd_u.dtu_members); 186 1.1 darran ctf_enum_t cte; 187 1.1 darran 188 1.1 darran for (; dmd != NULL; dmd = ctf_list_next(dmd)) { 189 1.1 darran cte.cte_name = soff; 190 1.1 darran cte.cte_value = dmd->dmd_value; 191 1.1 darran soff += strlen(dmd->dmd_name) + 1; 192 1.8 christos memcpy(t, &cte, sizeof (cte)); 193 1.1 darran t += sizeof (cte); 194 1.1 darran } 195 1.1 darran 196 1.1 darran return (t); 197 1.1 darran } 198 1.1 darran 199 1.1 darran static uchar_t * 200 1.1 darran ctf_copy_membnames(ctf_dtdef_t *dtd, uchar_t *s) 201 1.1 darran { 202 1.1 darran ctf_dmdef_t *dmd = ctf_list_next(&dtd->dtd_u.dtu_members); 203 1.1 darran size_t len; 204 1.1 darran 205 1.1 darran for (; dmd != NULL; dmd = ctf_list_next(dmd)) { 206 1.1 darran if (dmd->dmd_name == NULL) 207 1.1 darran continue; /* skip anonymous members */ 208 1.1 darran len = strlen(dmd->dmd_name) + 1; 209 1.8 christos memcpy(s, dmd->dmd_name, len); 210 1.1 darran s += len; 211 1.1 darran } 212 1.1 darran 213 1.1 darran return (s); 214 1.1 darran } 215 1.1 darran 216 1.1 darran /* 217 1.4 christos * Only types of dyanmic CTF containers contain reference counts. These 218 1.4 christos * containers are marked RD/WR. Because of that we basically make this a no-op 219 1.4 christos * for compatability with non-dynamic CTF sections. This is also a no-op for 220 1.4 christos * types which are not dynamic types. It is the responsibility of the caller to 221 1.4 christos * make sure it is a valid type. We help that caller out on debug builds. 222 1.4 christos * 223 1.4 christos * Note that the reference counts are not maintained for types that are not 224 1.4 christos * within this container. In other words if we have a type in a parent, that 225 1.4 christos * will not have its reference count increased. On the flip side, the parent 226 1.4 christos * will not be allowed to remove dynamic types if it has children. 227 1.4 christos */ 228 1.4 christos static void 229 1.4 christos ctf_ref_inc(ctf_file_t *fp, ctf_id_t tid) 230 1.4 christos { 231 1.4 christos ctf_dtdef_t *dtd = ctf_dtd_lookup(fp, tid); 232 1.4 christos 233 1.4 christos if (dtd == NULL) 234 1.4 christos return; 235 1.4 christos 236 1.4 christos if (!(fp->ctf_flags & LCTF_RDWR)) 237 1.4 christos return; 238 1.4 christos 239 1.4 christos dtd->dtd_ref++; 240 1.4 christos } 241 1.4 christos 242 1.4 christos /* 243 1.4 christos * Just as with ctf_ref_inc, this is a no-op on non-writeable containers and the 244 1.4 christos * caller should ensure that this is already a valid type. 245 1.4 christos */ 246 1.4 christos static void 247 1.4 christos ctf_ref_dec(ctf_file_t *fp, ctf_id_t tid) 248 1.4 christos { 249 1.4 christos ctf_dtdef_t *dtd = ctf_dtd_lookup(fp, tid); 250 1.4 christos 251 1.4 christos if (dtd == NULL) 252 1.4 christos return; 253 1.4 christos 254 1.4 christos if (!(fp->ctf_flags & LCTF_RDWR)) 255 1.4 christos return; 256 1.4 christos 257 1.4 christos ASSERT(dtd->dtd_ref >= 1); 258 1.4 christos dtd->dtd_ref--; 259 1.4 christos } 260 1.4 christos 261 1.4 christos /* 262 1.1 darran * If the specified CTF container is writable and has been modified, reload 263 1.1 darran * this container with the updated type definitions. In order to make this 264 1.1 darran * code and the rest of libctf as simple as possible, we perform updates by 265 1.1 darran * taking the dynamic type definitions and creating an in-memory CTF file 266 1.1 darran * containing the definitions, and then call ctf_bufopen() on it. This not 267 1.1 darran * only leverages ctf_bufopen(), but also avoids having to bifurcate the rest 268 1.1 darran * of the library code with different lookup paths for static and dynamic 269 1.1 darran * type definitions. We are therefore optimizing greatly for lookup over 270 1.1 darran * update, which we assume will be an uncommon operation. We perform one 271 1.1 darran * extra trick here for the benefit of callers and to keep our code simple: 272 1.1 darran * ctf_bufopen() will return a new ctf_file_t, but we want to keep the fp 273 1.8 christos * constant for the caller, so after ctf_bufopen() returns, we use memcpy to 274 1.1 darran * swap the interior of the old and new ctf_file_t's, and then free the old. 275 1.4 christos * 276 1.4 christos * Note that the lists of dynamic types stays around and the resulting container 277 1.4 christos * is still writeable. Furthermore, the reference counts that are on the dtd's 278 1.4 christos * are still valid. 279 1.1 darran */ 280 1.1 darran int 281 1.1 darran ctf_update(ctf_file_t *fp) 282 1.1 darran { 283 1.1 darran ctf_file_t ofp, *nfp; 284 1.1 darran ctf_header_t hdr; 285 1.1 darran ctf_dtdef_t *dtd; 286 1.1 darran ctf_sect_t cts; 287 1.1 darran 288 1.1 darran uchar_t *s, *s0, *t; 289 1.1 darran size_t size; 290 1.1 darran void *buf; 291 1.1 darran int err; 292 1.1 darran 293 1.1 darran if (!(fp->ctf_flags & LCTF_RDWR)) 294 1.1 darran return (ctf_set_errno(fp, ECTF_RDONLY)); 295 1.1 darran 296 1.1 darran if (!(fp->ctf_flags & LCTF_DIRTY)) 297 1.1 darran return (0); /* no update required */ 298 1.1 darran 299 1.1 darran /* 300 1.1 darran * Fill in an initial CTF header. We will leave the label, object, 301 1.1 darran * and function sections empty and only output a header, type section, 302 1.1 darran * and string table. The type section begins at a 4-byte aligned 303 1.1 darran * boundary past the CTF header itself (at relative offset zero). 304 1.1 darran */ 305 1.8 christos memset(&hdr, 0, sizeof (hdr)); 306 1.1 darran hdr.cth_magic = CTF_MAGIC; 307 1.8 christos hdr.cth_version = fp->ctf_version; 308 1.1 darran 309 1.1 darran if (fp->ctf_flags & LCTF_CHILD) 310 1.1 darran hdr.cth_parname = 1; /* i.e. _CTF_STRTAB_TEMPLATE[1] */ 311 1.1 darran 312 1.1 darran /* 313 1.1 darran * Iterate through the dynamic type definition list and compute the 314 1.1 darran * size of the CTF type section we will need to generate. 315 1.1 darran */ 316 1.1 darran for (size = 0, dtd = ctf_list_next(&fp->ctf_dtdefs); 317 1.1 darran dtd != NULL; dtd = ctf_list_next(dtd)) { 318 1.1 darran 319 1.8 christos uint_t kind = LCTF_INFO_KIND(fp, dtd->dtd_data.ctt_info); 320 1.8 christos uint_t vlen = LCTF_INFO_VLEN(fp, dtd->dtd_data.ctt_info); 321 1.1 darran 322 1.8 christos if (fp->ctf_version == CTF_VERSION_2) { 323 1.8 christos if (dtd->dtd_data.ctt_size != CTF_V2_LSIZE_SENT) 324 1.8 christos size += sizeof (struct ctf_stype_v2); 325 1.8 christos else 326 1.8 christos size += sizeof (struct ctf_type_v2); 327 1.8 christos } else { 328 1.8 christos if (dtd->dtd_data.ctt_size != LCTF_LSIZE_SENT(fp)) 329 1.8 christos size += sizeof (struct ctf_stype_v3); 330 1.8 christos else 331 1.8 christos size += sizeof (struct ctf_type_v3); 332 1.8 christos } 333 1.1 darran 334 1.1 darran switch (kind) { 335 1.1 darran case CTF_K_INTEGER: 336 1.1 darran case CTF_K_FLOAT: 337 1.1 darran size += sizeof (uint_t); 338 1.1 darran break; 339 1.1 darran case CTF_K_ARRAY: 340 1.8 christos size += fp->ctf_version == CTF_VERSION_2 ? 341 1.8 christos sizeof (struct ctf_array_v2) : 342 1.8 christos sizeof (struct ctf_array_v3); 343 1.1 darran break; 344 1.1 darran case CTF_K_FUNCTION: 345 1.8 christos size += roundup2(fp->ctf_idwidth * vlen, 4); 346 1.1 darran break; 347 1.1 darran case CTF_K_STRUCT: 348 1.1 darran case CTF_K_UNION: 349 1.8 christos if (fp->ctf_version == CTF_VERSION_2) { 350 1.8 christos if (dtd->dtd_data.ctt_size < 351 1.8 christos LCTF_LSTRUCT_THRESH(fp)) 352 1.8 christos size += sizeof (struct ctf_member_v2) * 353 1.8 christos vlen; 354 1.8 christos else 355 1.8 christos size += sizeof (struct ctf_lmember_v2) * 356 1.8 christos vlen; 357 1.8 christos } else { 358 1.8 christos if (dtd->dtd_data.ctt_size < 359 1.8 christos LCTF_LSTRUCT_THRESH(fp)) 360 1.8 christos size += sizeof (struct ctf_member_v3) * 361 1.8 christos vlen; 362 1.8 christos else 363 1.8 christos size += sizeof (struct ctf_lmember_v3) * 364 1.8 christos vlen; 365 1.8 christos } 366 1.1 darran break; 367 1.1 darran case CTF_K_ENUM: 368 1.1 darran size += sizeof (ctf_enum_t) * vlen; 369 1.1 darran break; 370 1.1 darran } 371 1.1 darran } 372 1.1 darran 373 1.1 darran /* 374 1.1 darran * Fill in the string table offset and size, compute the size of the 375 1.1 darran * entire CTF buffer we need, and then allocate a new buffer and 376 1.8 christos * memcpy the finished header to the start of the buffer. 377 1.1 darran */ 378 1.1 darran hdr.cth_stroff = hdr.cth_typeoff + size; 379 1.1 darran hdr.cth_strlen = fp->ctf_dtstrlen; 380 1.1 darran size = sizeof (ctf_header_t) + hdr.cth_stroff + hdr.cth_strlen; 381 1.1 darran 382 1.1 darran if ((buf = ctf_data_alloc(size)) == MAP_FAILED) 383 1.1 darran return (ctf_set_errno(fp, EAGAIN)); 384 1.1 darran 385 1.8 christos memcpy(buf, &hdr, sizeof (ctf_header_t)); 386 1.1 darran t = (uchar_t *)buf + sizeof (ctf_header_t); 387 1.1 darran s = s0 = (uchar_t *)buf + sizeof (ctf_header_t) + hdr.cth_stroff; 388 1.1 darran 389 1.8 christos memcpy(s, _CTF_STRTAB_TEMPLATE, sizeof (_CTF_STRTAB_TEMPLATE)); 390 1.1 darran s += sizeof (_CTF_STRTAB_TEMPLATE); 391 1.1 darran 392 1.1 darran /* 393 1.1 darran * We now take a final lap through the dynamic type definition list and 394 1.1 darran * copy the appropriate type records and strings to the output buffer. 395 1.1 darran */ 396 1.1 darran for (dtd = ctf_list_next(&fp->ctf_dtdefs); 397 1.1 darran dtd != NULL; dtd = ctf_list_next(dtd)) { 398 1.8 christos void *tp; 399 1.8 christos uint_t kind = LCTF_INFO_KIND(fp, dtd->dtd_data.ctt_info); 400 1.8 christos uint_t vlen = LCTF_INFO_VLEN(fp, dtd->dtd_data.ctt_info); 401 1.8 christos struct ctf_type_v2 ctt; 402 1.1 darran 403 1.1 darran uint_t encoding; 404 1.1 darran size_t len; 405 1.1 darran 406 1.1 darran if (dtd->dtd_name != NULL) { 407 1.1 darran dtd->dtd_data.ctt_name = (uint_t)(s - s0); 408 1.1 darran len = strlen(dtd->dtd_name) + 1; 409 1.8 christos memcpy(s, dtd->dtd_name, len); 410 1.1 darran s += len; 411 1.1 darran } else 412 1.1 darran dtd->dtd_data.ctt_name = 0; 413 1.1 darran 414 1.8 christos if (fp->ctf_version == CTF_VERSION_2) { 415 1.8 christos ctt.ctt_name = dtd->dtd_data.ctt_name; 416 1.8 christos ctt.ctt_info = (ushort_t)dtd->dtd_data.ctt_info; 417 1.8 christos ctt.ctt_size = (ushort_t)dtd->dtd_data.ctt_size; 418 1.8 christos if (dtd->dtd_data.ctt_size != CTF_V2_LSIZE_SENT) 419 1.8 christos len = sizeof (struct ctf_stype_v2); 420 1.8 christos else { 421 1.8 christos len = sizeof (struct ctf_type_v2); 422 1.8 christos ctt.ctt_lsizehi = dtd->dtd_data.ctt_lsizehi; 423 1.8 christos ctt.ctt_lsizelo = dtd->dtd_data.ctt_lsizelo; 424 1.8 christos } 425 1.8 christos tp = &ctt; 426 1.8 christos } else { 427 1.8 christos if (dtd->dtd_data.ctt_size != LCTF_LSIZE_SENT(fp)) 428 1.8 christos len = sizeof (struct ctf_stype_v3); 429 1.8 christos else 430 1.8 christos len = sizeof (struct ctf_type_v3); 431 1.8 christos tp = &dtd->dtd_data; 432 1.8 christos } 433 1.1 darran 434 1.8 christos memcpy(t, tp, len); 435 1.1 darran t += len; 436 1.1 darran 437 1.1 darran switch (kind) { 438 1.1 darran case CTF_K_INTEGER: 439 1.1 darran case CTF_K_FLOAT: 440 1.1 darran if (kind == CTF_K_INTEGER) { 441 1.1 darran encoding = CTF_INT_DATA( 442 1.1 darran dtd->dtd_u.dtu_enc.cte_format, 443 1.1 darran dtd->dtd_u.dtu_enc.cte_offset, 444 1.1 darran dtd->dtd_u.dtu_enc.cte_bits); 445 1.1 darran } else { 446 1.1 darran encoding = CTF_FP_DATA( 447 1.1 darran dtd->dtd_u.dtu_enc.cte_format, 448 1.1 darran dtd->dtd_u.dtu_enc.cte_offset, 449 1.1 darran dtd->dtd_u.dtu_enc.cte_bits); 450 1.1 darran } 451 1.8 christos memcpy(t, &encoding, sizeof (encoding)); 452 1.1 darran t += sizeof (encoding); 453 1.1 darran break; 454 1.1 darran 455 1.1 darran case CTF_K_ARRAY: 456 1.8 christos if (fp->ctf_version == CTF_VERSION_2) { 457 1.8 christos struct ctf_array_v2 cta; 458 1.8 christos 459 1.8 christos cta.cta_contents = 460 1.8 christos (uint16_t)dtd->dtd_u.dtu_arr.ctr_contents; 461 1.8 christos cta.cta_index = 462 1.8 christos (uint16_t)dtd->dtd_u.dtu_arr.ctr_index; 463 1.8 christos cta.cta_nelems = dtd->dtd_u.dtu_arr.ctr_nelems; 464 1.8 christos 465 1.8 christos memcpy(t, &cta, sizeof (cta)); 466 1.8 christos t += sizeof (cta); 467 1.8 christos } else { 468 1.8 christos struct ctf_array_v3 cta; 469 1.8 christos 470 1.8 christos cta.cta_contents = 471 1.8 christos dtd->dtd_u.dtu_arr.ctr_contents; 472 1.8 christos cta.cta_index = dtd->dtd_u.dtu_arr.ctr_index; 473 1.8 christos cta.cta_nelems = dtd->dtd_u.dtu_arr.ctr_nelems; 474 1.8 christos 475 1.8 christos memcpy(t, &cta, sizeof (cta)); 476 1.8 christos t += sizeof (cta); 477 1.8 christos } 478 1.1 darran break; 479 1.1 darran 480 1.1 darran case CTF_K_FUNCTION: { 481 1.8 christos char *argv = (char *)(uintptr_t)t; 482 1.1 darran uint_t argc; 483 1.1 darran 484 1.8 christos if (fp->ctf_version == CTF_VERSION_2) { 485 1.8 christos ushort_t arg; 486 1.1 darran 487 1.8 christos for (argc = 0; argc < vlen; 488 1.8 christos argc++, argv += sizeof(arg)) { 489 1.8 christos arg = 490 1.8 christos (ushort_t)dtd->dtd_u.dtu_argv[argc]; 491 1.8 christos memcpy(argv, &arg, sizeof(arg)); 492 1.8 christos } 493 1.8 christos } else { 494 1.8 christos uint_t arg; 495 1.8 christos 496 1.8 christos for (argc = 0; argc < vlen; 497 1.8 christos argc++, argv += sizeof(arg)) { 498 1.8 christos arg = (uint_t)dtd->dtd_u.dtu_argv[argc]; 499 1.8 christos memcpy(argv, &arg, sizeof(arg)); 500 1.8 christos } 501 1.8 christos } 502 1.1 darran 503 1.1 darran t = (uchar_t *)argv; 504 1.1 darran break; 505 1.1 darran } 506 1.1 darran 507 1.1 darran case CTF_K_STRUCT: 508 1.1 darran case CTF_K_UNION: 509 1.8 christos if (dtd->dtd_data.ctt_size < LCTF_LSTRUCT_THRESH(fp)) 510 1.8 christos t = ctf_copy_smembers(fp, dtd, (uint_t)(s - s0), 511 1.8 christos t); 512 1.1 darran else 513 1.8 christos t = ctf_copy_lmembers(fp, dtd, (uint_t)(s - s0), 514 1.8 christos t); 515 1.1 darran s = ctf_copy_membnames(dtd, s); 516 1.1 darran break; 517 1.1 darran 518 1.1 darran case CTF_K_ENUM: 519 1.1 darran t = ctf_copy_emembers(dtd, (uint_t)(s - s0), t); 520 1.1 darran s = ctf_copy_membnames(dtd, s); 521 1.1 darran break; 522 1.1 darran } 523 1.1 darran } 524 1.1 darran 525 1.1 darran /* 526 1.1 darran * Finally, we are ready to ctf_bufopen() the new container. If this 527 1.1 darran * is successful, we then switch nfp and fp and free the old container. 528 1.1 darran */ 529 1.1 darran ctf_data_protect(buf, size); 530 1.4 christos cts.cts_name = _CTF_SECTION; 531 1.1 darran cts.cts_type = SHT_PROGBITS; 532 1.1 darran cts.cts_flags = 0; 533 1.1 darran cts.cts_data = buf; 534 1.1 darran cts.cts_size = size; 535 1.1 darran cts.cts_entsize = 1; 536 1.1 darran cts.cts_offset = 0; 537 1.1 darran 538 1.1 darran if ((nfp = ctf_bufopen(&cts, NULL, NULL, &err)) == NULL) { 539 1.1 darran ctf_data_free(buf, size); 540 1.1 darran return (ctf_set_errno(fp, err)); 541 1.1 darran } 542 1.1 darran 543 1.1 darran (void) ctf_setmodel(nfp, ctf_getmodel(fp)); 544 1.1 darran (void) ctf_import(nfp, fp->ctf_parent); 545 1.1 darran 546 1.1 darran nfp->ctf_refcnt = fp->ctf_refcnt; 547 1.1 darran nfp->ctf_flags |= fp->ctf_flags & ~LCTF_DIRTY; 548 1.1 darran nfp->ctf_data.cts_data = NULL; /* force ctf_data_free() on close */ 549 1.1 darran nfp->ctf_dthash = fp->ctf_dthash; 550 1.1 darran nfp->ctf_dthashlen = fp->ctf_dthashlen; 551 1.1 darran nfp->ctf_dtdefs = fp->ctf_dtdefs; 552 1.1 darran nfp->ctf_dtstrlen = fp->ctf_dtstrlen; 553 1.1 darran nfp->ctf_dtnextid = fp->ctf_dtnextid; 554 1.1 darran nfp->ctf_dtoldid = fp->ctf_dtnextid - 1; 555 1.1 darran nfp->ctf_specific = fp->ctf_specific; 556 1.1 darran 557 1.1 darran fp->ctf_dthash = NULL; 558 1.1 darran fp->ctf_dthashlen = 0; 559 1.8 christos memset(&fp->ctf_dtdefs, 0, sizeof (ctf_list_t)); 560 1.1 darran 561 1.8 christos memcpy(&ofp, fp, sizeof (ctf_file_t)); 562 1.8 christos memcpy(fp, nfp, sizeof (ctf_file_t)); 563 1.8 christos memcpy(nfp, &ofp, sizeof (ctf_file_t)); 564 1.1 darran 565 1.1 darran /* 566 1.1 darran * Initialize the ctf_lookup_by_name top-level dictionary. We keep an 567 1.1 darran * array of type name prefixes and the corresponding ctf_hash to use. 568 1.1 darran * NOTE: This code must be kept in sync with the code in ctf_bufopen(). 569 1.1 darran */ 570 1.1 darran fp->ctf_lookups[0].ctl_hash = &fp->ctf_structs; 571 1.1 darran fp->ctf_lookups[1].ctl_hash = &fp->ctf_unions; 572 1.1 darran fp->ctf_lookups[2].ctl_hash = &fp->ctf_enums; 573 1.1 darran fp->ctf_lookups[3].ctl_hash = &fp->ctf_names; 574 1.1 darran 575 1.1 darran nfp->ctf_refcnt = 1; /* force nfp to be freed */ 576 1.1 darran ctf_close(nfp); 577 1.1 darran 578 1.1 darran return (0); 579 1.1 darran } 580 1.1 darran 581 1.1 darran void 582 1.1 darran ctf_dtd_insert(ctf_file_t *fp, ctf_dtdef_t *dtd) 583 1.1 darran { 584 1.1 darran ulong_t h = dtd->dtd_type & (fp->ctf_dthashlen - 1); 585 1.1 darran 586 1.1 darran dtd->dtd_hash = fp->ctf_dthash[h]; 587 1.1 darran fp->ctf_dthash[h] = dtd; 588 1.1 darran ctf_list_append(&fp->ctf_dtdefs, dtd); 589 1.1 darran } 590 1.1 darran 591 1.1 darran void 592 1.1 darran ctf_dtd_delete(ctf_file_t *fp, ctf_dtdef_t *dtd) 593 1.1 darran { 594 1.1 darran ulong_t h = dtd->dtd_type & (fp->ctf_dthashlen - 1); 595 1.1 darran ctf_dtdef_t *p, **q = &fp->ctf_dthash[h]; 596 1.1 darran ctf_dmdef_t *dmd, *nmd; 597 1.1 darran size_t len; 598 1.4 christos int kind, i; 599 1.1 darran 600 1.1 darran for (p = *q; p != NULL; p = p->dtd_hash) { 601 1.1 darran if (p != dtd) 602 1.1 darran q = &p->dtd_hash; 603 1.1 darran else 604 1.1 darran break; 605 1.1 darran } 606 1.1 darran 607 1.1 darran if (p != NULL) 608 1.1 darran *q = p->dtd_hash; 609 1.1 darran 610 1.8 christos kind = LCTF_INFO_KIND(fp, dtd->dtd_data.ctt_info); 611 1.4 christos switch (kind) { 612 1.1 darran case CTF_K_STRUCT: 613 1.1 darran case CTF_K_UNION: 614 1.1 darran case CTF_K_ENUM: 615 1.1 darran for (dmd = ctf_list_next(&dtd->dtd_u.dtu_members); 616 1.1 darran dmd != NULL; dmd = nmd) { 617 1.1 darran if (dmd->dmd_name != NULL) { 618 1.1 darran len = strlen(dmd->dmd_name) + 1; 619 1.1 darran ctf_free(dmd->dmd_name, len); 620 1.1 darran fp->ctf_dtstrlen -= len; 621 1.1 darran } 622 1.4 christos if (kind != CTF_K_ENUM) 623 1.4 christos ctf_ref_dec(fp, dmd->dmd_type); 624 1.1 darran nmd = ctf_list_next(dmd); 625 1.1 darran ctf_free(dmd, sizeof (ctf_dmdef_t)); 626 1.1 darran } 627 1.1 darran break; 628 1.1 darran case CTF_K_FUNCTION: 629 1.4 christos ctf_ref_dec(fp, dtd->dtd_data.ctt_type); 630 1.8 christos for (i = 0; i < LCTF_INFO_VLEN(fp, dtd->dtd_data.ctt_info); i++) 631 1.4 christos if (dtd->dtd_u.dtu_argv[i] != 0) 632 1.4 christos ctf_ref_dec(fp, dtd->dtd_u.dtu_argv[i]); 633 1.1 darran ctf_free(dtd->dtd_u.dtu_argv, sizeof (ctf_id_t) * 634 1.8 christos LCTF_INFO_VLEN(fp, dtd->dtd_data.ctt_info)); 635 1.1 darran break; 636 1.4 christos case CTF_K_ARRAY: 637 1.4 christos ctf_ref_dec(fp, dtd->dtd_u.dtu_arr.ctr_contents); 638 1.4 christos ctf_ref_dec(fp, dtd->dtd_u.dtu_arr.ctr_index); 639 1.4 christos break; 640 1.4 christos case CTF_K_TYPEDEF: 641 1.4 christos ctf_ref_dec(fp, dtd->dtd_data.ctt_type); 642 1.4 christos break; 643 1.4 christos case CTF_K_POINTER: 644 1.4 christos case CTF_K_VOLATILE: 645 1.4 christos case CTF_K_CONST: 646 1.4 christos case CTF_K_RESTRICT: 647 1.4 christos ctf_ref_dec(fp, dtd->dtd_data.ctt_type); 648 1.4 christos break; 649 1.1 darran } 650 1.1 darran 651 1.1 darran if (dtd->dtd_name) { 652 1.1 darran len = strlen(dtd->dtd_name) + 1; 653 1.1 darran ctf_free(dtd->dtd_name, len); 654 1.1 darran fp->ctf_dtstrlen -= len; 655 1.1 darran } 656 1.1 darran 657 1.1 darran ctf_list_delete(&fp->ctf_dtdefs, dtd); 658 1.1 darran ctf_free(dtd, sizeof (ctf_dtdef_t)); 659 1.1 darran } 660 1.1 darran 661 1.1 darran ctf_dtdef_t * 662 1.1 darran ctf_dtd_lookup(ctf_file_t *fp, ctf_id_t type) 663 1.1 darran { 664 1.1 darran ulong_t h = type & (fp->ctf_dthashlen - 1); 665 1.1 darran ctf_dtdef_t *dtd; 666 1.1 darran 667 1.1 darran if (fp->ctf_dthash == NULL) 668 1.1 darran return (NULL); 669 1.1 darran 670 1.1 darran for (dtd = fp->ctf_dthash[h]; dtd != NULL; dtd = dtd->dtd_hash) { 671 1.1 darran if (dtd->dtd_type == type) 672 1.1 darran break; 673 1.1 darran } 674 1.1 darran 675 1.1 darran return (dtd); 676 1.1 darran } 677 1.1 darran 678 1.1 darran /* 679 1.1 darran * Discard all of the dynamic type definitions that have been added to the 680 1.1 darran * container since the last call to ctf_update(). We locate such types by 681 1.1 darran * scanning the list and deleting elements that have type IDs greater than 682 1.4 christos * ctf_dtoldid, which is set by ctf_update(), above. Note that to work properly 683 1.4 christos * with our reference counting schemes, we must delete the dynamic list in 684 1.4 christos * reverse. 685 1.1 darran */ 686 1.1 darran int 687 1.1 darran ctf_discard(ctf_file_t *fp) 688 1.1 darran { 689 1.4 christos ctf_dtdef_t *dtd, *ntd; 690 1.1 darran 691 1.1 darran if (!(fp->ctf_flags & LCTF_RDWR)) 692 1.1 darran return (ctf_set_errno(fp, ECTF_RDONLY)); 693 1.1 darran 694 1.1 darran if (!(fp->ctf_flags & LCTF_DIRTY)) 695 1.1 darran return (0); /* no update required */ 696 1.1 darran 697 1.4 christos for (dtd = ctf_list_prev(&fp->ctf_dtdefs); dtd != NULL; dtd = ntd) { 698 1.4 christos ntd = ctf_list_prev(dtd); 699 1.8 christos if (LCTF_TYPE_TO_INDEX(fp, dtd->dtd_type) <= fp->ctf_dtoldid) 700 1.1 darran continue; /* skip types that have been committed */ 701 1.1 darran 702 1.1 darran ctf_dtd_delete(fp, dtd); 703 1.1 darran } 704 1.1 darran 705 1.1 darran fp->ctf_dtnextid = fp->ctf_dtoldid + 1; 706 1.1 darran fp->ctf_flags &= ~LCTF_DIRTY; 707 1.1 darran 708 1.1 darran return (0); 709 1.1 darran } 710 1.1 darran 711 1.1 darran static ctf_id_t 712 1.1 darran ctf_add_generic(ctf_file_t *fp, uint_t flag, const char *name, ctf_dtdef_t **rp) 713 1.1 darran { 714 1.1 darran ctf_dtdef_t *dtd; 715 1.1 darran ctf_id_t type; 716 1.1 darran char *s = NULL; 717 1.1 darran 718 1.1 darran if (flag != CTF_ADD_NONROOT && flag != CTF_ADD_ROOT) 719 1.1 darran return (ctf_set_errno(fp, EINVAL)); 720 1.1 darran 721 1.1 darran if (!(fp->ctf_flags & LCTF_RDWR)) 722 1.1 darran return (ctf_set_errno(fp, ECTF_RDONLY)); 723 1.1 darran 724 1.8 christos if (LCTF_INDEX_TO_TYPE(fp, fp->ctf_dtnextid, 1) > LCTF_MAX_TYPE(fp)) { 725 1.7 christos ctf_dprintf("type id overflow %lu\n", fp->ctf_dtnextid); 726 1.1 darran return (ctf_set_errno(fp, ECTF_FULL)); 727 1.7 christos } 728 1.1 darran 729 1.1 darran if ((dtd = ctf_alloc(sizeof (ctf_dtdef_t))) == NULL) 730 1.1 darran return (ctf_set_errno(fp, EAGAIN)); 731 1.1 darran 732 1.8 christos if (name != NULL && *name != '\0' && (s = ctf_strdup(name)) == NULL) { 733 1.1 darran ctf_free(dtd, sizeof (ctf_dtdef_t)); 734 1.1 darran return (ctf_set_errno(fp, EAGAIN)); 735 1.1 darran } 736 1.1 darran 737 1.1 darran type = fp->ctf_dtnextid++; 738 1.8 christos type = LCTF_INDEX_TO_TYPE(fp, type, (fp->ctf_flags & LCTF_CHILD)); 739 1.1 darran 740 1.8 christos memset(dtd, 0, sizeof (ctf_dtdef_t)); 741 1.1 darran dtd->dtd_name = s; 742 1.1 darran dtd->dtd_type = type; 743 1.1 darran 744 1.1 darran if (s != NULL) 745 1.1 darran fp->ctf_dtstrlen += strlen(s) + 1; 746 1.1 darran 747 1.1 darran ctf_dtd_insert(fp, dtd); 748 1.1 darran fp->ctf_flags |= LCTF_DIRTY; 749 1.1 darran 750 1.1 darran *rp = dtd; 751 1.1 darran return (type); 752 1.1 darran } 753 1.1 darran 754 1.1 darran /* 755 1.1 darran * When encoding integer sizes, we want to convert a byte count in the range 756 1.1 darran * 1-8 to the closest power of 2 (e.g. 3->4, 5->8, etc). The clp2() function 757 1.1 darran * is a clever implementation from "Hacker's Delight" by Henry Warren, Jr. 758 1.1 darran */ 759 1.1 darran static size_t 760 1.1 darran clp2(size_t x) 761 1.1 darran { 762 1.1 darran x--; 763 1.1 darran 764 1.1 darran x |= (x >> 1); 765 1.1 darran x |= (x >> 2); 766 1.1 darran x |= (x >> 4); 767 1.1 darran x |= (x >> 8); 768 1.1 darran x |= (x >> 16); 769 1.1 darran 770 1.1 darran return (x + 1); 771 1.1 darran } 772 1.1 darran 773 1.1 darran static ctf_id_t 774 1.1 darran ctf_add_encoded(ctf_file_t *fp, uint_t flag, 775 1.1 darran const char *name, const ctf_encoding_t *ep, uint_t kind) 776 1.1 darran { 777 1.1 darran ctf_dtdef_t *dtd; 778 1.1 darran ctf_id_t type; 779 1.1 darran 780 1.1 darran if (ep == NULL) 781 1.1 darran return (ctf_set_errno(fp, EINVAL)); 782 1.1 darran 783 1.1 darran if ((type = ctf_add_generic(fp, flag, name, &dtd)) == CTF_ERR) 784 1.1 darran return (CTF_ERR); /* errno is set for us */ 785 1.1 darran 786 1.8 christos dtd->dtd_data.ctt_info = LCTF_TYPE_INFO(fp, kind, flag, 0); 787 1.1 darran dtd->dtd_data.ctt_size = clp2(P2ROUNDUP(ep->cte_bits, NBBY) / NBBY); 788 1.1 darran dtd->dtd_u.dtu_enc = *ep; 789 1.1 darran 790 1.1 darran return (type); 791 1.1 darran } 792 1.1 darran 793 1.1 darran static ctf_id_t 794 1.1 darran ctf_add_reftype(ctf_file_t *fp, uint_t flag, ctf_id_t ref, uint_t kind) 795 1.1 darran { 796 1.1 darran ctf_dtdef_t *dtd; 797 1.1 darran ctf_id_t type; 798 1.1 darran 799 1.9 hannken if (ref == CTF_ERR || ref > LCTF_MAX_TYPE(fp)) 800 1.1 darran return (ctf_set_errno(fp, EINVAL)); 801 1.1 darran 802 1.1 darran if ((type = ctf_add_generic(fp, flag, NULL, &dtd)) == CTF_ERR) 803 1.1 darran return (CTF_ERR); /* errno is set for us */ 804 1.1 darran 805 1.4 christos ctf_ref_inc(fp, ref); 806 1.4 christos 807 1.8 christos dtd->dtd_data.ctt_info = LCTF_TYPE_INFO(fp, kind, flag, 0); 808 1.8 christos dtd->dtd_data.ctt_type = (uint_t)ref; 809 1.1 darran 810 1.1 darran return (type); 811 1.1 darran } 812 1.1 darran 813 1.1 darran ctf_id_t 814 1.1 darran ctf_add_integer(ctf_file_t *fp, uint_t flag, 815 1.1 darran const char *name, const ctf_encoding_t *ep) 816 1.1 darran { 817 1.1 darran return (ctf_add_encoded(fp, flag, name, ep, CTF_K_INTEGER)); 818 1.1 darran } 819 1.1 darran 820 1.1 darran ctf_id_t 821 1.1 darran ctf_add_float(ctf_file_t *fp, uint_t flag, 822 1.1 darran const char *name, const ctf_encoding_t *ep) 823 1.1 darran { 824 1.1 darran return (ctf_add_encoded(fp, flag, name, ep, CTF_K_FLOAT)); 825 1.1 darran } 826 1.1 darran 827 1.1 darran ctf_id_t 828 1.1 darran ctf_add_pointer(ctf_file_t *fp, uint_t flag, ctf_id_t ref) 829 1.1 darran { 830 1.1 darran return (ctf_add_reftype(fp, flag, ref, CTF_K_POINTER)); 831 1.1 darran } 832 1.1 darran 833 1.1 darran ctf_id_t 834 1.1 darran ctf_add_array(ctf_file_t *fp, uint_t flag, const ctf_arinfo_t *arp) 835 1.1 darran { 836 1.1 darran ctf_dtdef_t *dtd; 837 1.1 darran ctf_id_t type; 838 1.4 christos ctf_file_t *fpd; 839 1.1 darran 840 1.1 darran if (arp == NULL) 841 1.1 darran return (ctf_set_errno(fp, EINVAL)); 842 1.1 darran 843 1.4 christos fpd = fp; 844 1.4 christos if (ctf_lookup_by_id(&fpd, arp->ctr_contents) == NULL && 845 1.4 christos ctf_dtd_lookup(fp, arp->ctr_contents) == NULL) 846 1.4 christos return (ctf_set_errno(fp, ECTF_BADID)); 847 1.4 christos 848 1.4 christos fpd = fp; 849 1.4 christos if (ctf_lookup_by_id(&fpd, arp->ctr_index) == NULL && 850 1.4 christos ctf_dtd_lookup(fp, arp->ctr_index) == NULL) 851 1.4 christos return (ctf_set_errno(fp, ECTF_BADID)); 852 1.4 christos 853 1.1 darran if ((type = ctf_add_generic(fp, flag, NULL, &dtd)) == CTF_ERR) 854 1.1 darran return (CTF_ERR); /* errno is set for us */ 855 1.1 darran 856 1.8 christos dtd->dtd_data.ctt_info = LCTF_TYPE_INFO(fp, CTF_K_ARRAY, flag, 0); 857 1.1 darran dtd->dtd_data.ctt_size = 0; 858 1.1 darran dtd->dtd_u.dtu_arr = *arp; 859 1.4 christos ctf_ref_inc(fp, arp->ctr_contents); 860 1.4 christos ctf_ref_inc(fp, arp->ctr_index); 861 1.1 darran 862 1.1 darran return (type); 863 1.1 darran } 864 1.1 darran 865 1.1 darran int 866 1.1 darran ctf_set_array(ctf_file_t *fp, ctf_id_t type, const ctf_arinfo_t *arp) 867 1.1 darran { 868 1.4 christos ctf_file_t *fpd; 869 1.1 darran ctf_dtdef_t *dtd = ctf_dtd_lookup(fp, type); 870 1.1 darran 871 1.1 darran if (!(fp->ctf_flags & LCTF_RDWR)) 872 1.1 darran return (ctf_set_errno(fp, ECTF_RDONLY)); 873 1.1 darran 874 1.8 christos if (dtd == NULL || 875 1.8 christos LCTF_INFO_KIND(fp, dtd->dtd_data.ctt_info) != CTF_K_ARRAY) 876 1.1 darran return (ctf_set_errno(fp, ECTF_BADID)); 877 1.1 darran 878 1.4 christos fpd = fp; 879 1.4 christos if (ctf_lookup_by_id(&fpd, arp->ctr_contents) == NULL && 880 1.4 christos ctf_dtd_lookup(fp, arp->ctr_contents) == NULL) 881 1.4 christos return (ctf_set_errno(fp, ECTF_BADID)); 882 1.4 christos 883 1.4 christos fpd = fp; 884 1.4 christos if (ctf_lookup_by_id(&fpd, arp->ctr_index) == NULL && 885 1.4 christos ctf_dtd_lookup(fp, arp->ctr_index) == NULL) 886 1.4 christos return (ctf_set_errno(fp, ECTF_BADID)); 887 1.4 christos 888 1.4 christos ctf_ref_dec(fp, dtd->dtd_u.dtu_arr.ctr_contents); 889 1.4 christos ctf_ref_dec(fp, dtd->dtd_u.dtu_arr.ctr_index); 890 1.1 darran fp->ctf_flags |= LCTF_DIRTY; 891 1.1 darran dtd->dtd_u.dtu_arr = *arp; 892 1.4 christos ctf_ref_inc(fp, arp->ctr_contents); 893 1.4 christos ctf_ref_inc(fp, arp->ctr_index); 894 1.1 darran 895 1.1 darran return (0); 896 1.1 darran } 897 1.1 darran 898 1.1 darran ctf_id_t 899 1.1 darran ctf_add_function(ctf_file_t *fp, uint_t flag, 900 1.1 darran const ctf_funcinfo_t *ctc, const ctf_id_t *argv) 901 1.1 darran { 902 1.1 darran ctf_dtdef_t *dtd; 903 1.1 darran ctf_id_t type; 904 1.1 darran uint_t vlen; 905 1.4 christos int i; 906 1.1 darran ctf_id_t *vdat = NULL; 907 1.4 christos ctf_file_t *fpd; 908 1.1 darran 909 1.1 darran if (ctc == NULL || (ctc->ctc_flags & ~CTF_FUNC_VARARG) != 0 || 910 1.1 darran (ctc->ctc_argc != 0 && argv == NULL)) 911 1.1 darran return (ctf_set_errno(fp, EINVAL)); 912 1.1 darran 913 1.1 darran vlen = ctc->ctc_argc; 914 1.1 darran if (ctc->ctc_flags & CTF_FUNC_VARARG) 915 1.1 darran vlen++; /* add trailing zero to indicate varargs (see below) */ 916 1.1 darran 917 1.8 christos if (vlen > LCTF_MAX_VLEN(fp)) 918 1.1 darran return (ctf_set_errno(fp, EOVERFLOW)); 919 1.1 darran 920 1.4 christos fpd = fp; 921 1.4 christos if (ctf_lookup_by_id(&fpd, ctc->ctc_return) == NULL && 922 1.4 christos ctf_dtd_lookup(fp, ctc->ctc_return) == NULL) 923 1.4 christos return (ctf_set_errno(fp, ECTF_BADID)); 924 1.4 christos 925 1.4 christos for (i = 0; i < ctc->ctc_argc; i++) { 926 1.4 christos fpd = fp; 927 1.4 christos if (ctf_lookup_by_id(&fpd, argv[i]) == NULL && 928 1.4 christos ctf_dtd_lookup(fp, argv[i]) == NULL) 929 1.4 christos return (ctf_set_errno(fp, ECTF_BADID)); 930 1.4 christos } 931 1.4 christos 932 1.1 darran if (vlen != 0 && (vdat = ctf_alloc(sizeof (ctf_id_t) * vlen)) == NULL) 933 1.1 darran return (ctf_set_errno(fp, EAGAIN)); 934 1.1 darran 935 1.1 darran if ((type = ctf_add_generic(fp, flag, NULL, &dtd)) == CTF_ERR) { 936 1.1 darran ctf_free(vdat, sizeof (ctf_id_t) * vlen); 937 1.1 darran return (CTF_ERR); /* errno is set for us */ 938 1.1 darran } 939 1.1 darran 940 1.8 christos dtd->dtd_data.ctt_info = LCTF_TYPE_INFO(fp, CTF_K_FUNCTION, flag, vlen); 941 1.8 christos dtd->dtd_data.ctt_type = ctc->ctc_return; 942 1.1 darran 943 1.4 christos ctf_ref_inc(fp, ctc->ctc_return); 944 1.4 christos for (i = 0; i < ctc->ctc_argc; i++) 945 1.4 christos ctf_ref_inc(fp, argv[i]); 946 1.4 christos 947 1.8 christos memcpy(vdat, argv, sizeof (ctf_id_t) * ctc->ctc_argc); 948 1.1 darran if (ctc->ctc_flags & CTF_FUNC_VARARG) 949 1.1 darran vdat[vlen - 1] = 0; /* add trailing zero to indicate varargs */ 950 1.1 darran dtd->dtd_u.dtu_argv = vdat; 951 1.1 darran 952 1.1 darran return (type); 953 1.1 darran } 954 1.1 darran 955 1.1 darran ctf_id_t 956 1.1 darran ctf_add_struct(ctf_file_t *fp, uint_t flag, const char *name) 957 1.1 darran { 958 1.1 darran ctf_hash_t *hp = &fp->ctf_structs; 959 1.1 darran ctf_helem_t *hep = NULL; 960 1.1 darran ctf_dtdef_t *dtd; 961 1.1 darran ctf_id_t type; 962 1.1 darran 963 1.1 darran if (name != NULL) 964 1.1 darran hep = ctf_hash_lookup(hp, fp, name, strlen(name)); 965 1.1 darran 966 1.1 darran if (hep != NULL && ctf_type_kind(fp, hep->h_type) == CTF_K_FORWARD) 967 1.1 darran dtd = ctf_dtd_lookup(fp, type = hep->h_type); 968 1.1 darran else if ((type = ctf_add_generic(fp, flag, name, &dtd)) == CTF_ERR) 969 1.1 darran return (CTF_ERR); /* errno is set for us */ 970 1.1 darran 971 1.8 christos dtd->dtd_data.ctt_info = LCTF_TYPE_INFO(fp, CTF_K_STRUCT, flag, 0); 972 1.1 darran dtd->dtd_data.ctt_size = 0; 973 1.1 darran 974 1.1 darran return (type); 975 1.1 darran } 976 1.1 darran 977 1.1 darran ctf_id_t 978 1.1 darran ctf_add_union(ctf_file_t *fp, uint_t flag, const char *name) 979 1.1 darran { 980 1.1 darran ctf_hash_t *hp = &fp->ctf_unions; 981 1.1 darran ctf_helem_t *hep = NULL; 982 1.1 darran ctf_dtdef_t *dtd; 983 1.1 darran ctf_id_t type; 984 1.1 darran 985 1.1 darran if (name != NULL) 986 1.1 darran hep = ctf_hash_lookup(hp, fp, name, strlen(name)); 987 1.1 darran 988 1.1 darran if (hep != NULL && ctf_type_kind(fp, hep->h_type) == CTF_K_FORWARD) 989 1.1 darran dtd = ctf_dtd_lookup(fp, type = hep->h_type); 990 1.1 darran else if ((type = ctf_add_generic(fp, flag, name, &dtd)) == CTF_ERR) 991 1.1 darran return (CTF_ERR); /* errno is set for us */ 992 1.1 darran 993 1.8 christos dtd->dtd_data.ctt_info = LCTF_TYPE_INFO(fp, CTF_K_UNION, flag, 0); 994 1.1 darran dtd->dtd_data.ctt_size = 0; 995 1.1 darran 996 1.1 darran return (type); 997 1.1 darran } 998 1.1 darran 999 1.1 darran ctf_id_t 1000 1.1 darran ctf_add_enum(ctf_file_t *fp, uint_t flag, const char *name) 1001 1.1 darran { 1002 1.1 darran ctf_hash_t *hp = &fp->ctf_enums; 1003 1.1 darran ctf_helem_t *hep = NULL; 1004 1.1 darran ctf_dtdef_t *dtd; 1005 1.1 darran ctf_id_t type; 1006 1.1 darran 1007 1.1 darran if (name != NULL) 1008 1.1 darran hep = ctf_hash_lookup(hp, fp, name, strlen(name)); 1009 1.1 darran 1010 1.1 darran if (hep != NULL && ctf_type_kind(fp, hep->h_type) == CTF_K_FORWARD) 1011 1.1 darran dtd = ctf_dtd_lookup(fp, type = hep->h_type); 1012 1.1 darran else if ((type = ctf_add_generic(fp, flag, name, &dtd)) == CTF_ERR) 1013 1.1 darran return (CTF_ERR); /* errno is set for us */ 1014 1.1 darran 1015 1.8 christos dtd->dtd_data.ctt_info = LCTF_TYPE_INFO(fp, CTF_K_ENUM, flag, 0); 1016 1.1 darran dtd->dtd_data.ctt_size = fp->ctf_dmodel->ctd_int; 1017 1.1 darran 1018 1.1 darran return (type); 1019 1.1 darran } 1020 1.1 darran 1021 1.1 darran ctf_id_t 1022 1.1 darran ctf_add_forward(ctf_file_t *fp, uint_t flag, const char *name, uint_t kind) 1023 1.1 darran { 1024 1.1 darran ctf_hash_t *hp; 1025 1.1 darran ctf_helem_t *hep; 1026 1.1 darran ctf_dtdef_t *dtd; 1027 1.1 darran ctf_id_t type; 1028 1.1 darran 1029 1.1 darran switch (kind) { 1030 1.1 darran case CTF_K_STRUCT: 1031 1.1 darran hp = &fp->ctf_structs; 1032 1.1 darran break; 1033 1.1 darran case CTF_K_UNION: 1034 1.1 darran hp = &fp->ctf_unions; 1035 1.1 darran break; 1036 1.1 darran case CTF_K_ENUM: 1037 1.1 darran hp = &fp->ctf_enums; 1038 1.1 darran break; 1039 1.1 darran default: 1040 1.1 darran return (ctf_set_errno(fp, ECTF_NOTSUE)); 1041 1.1 darran } 1042 1.1 darran 1043 1.1 darran /* 1044 1.1 darran * If the type is already defined or exists as a forward tag, just 1045 1.1 darran * return the ctf_id_t of the existing definition. 1046 1.1 darran */ 1047 1.1 darran if (name != NULL && (hep = ctf_hash_lookup(hp, 1048 1.1 darran fp, name, strlen(name))) != NULL) 1049 1.1 darran return (hep->h_type); 1050 1.1 darran 1051 1.1 darran if ((type = ctf_add_generic(fp, flag, name, &dtd)) == CTF_ERR) 1052 1.1 darran return (CTF_ERR); /* errno is set for us */ 1053 1.1 darran 1054 1.8 christos dtd->dtd_data.ctt_info = LCTF_TYPE_INFO(fp, CTF_K_FORWARD, flag, 0); 1055 1.1 darran dtd->dtd_data.ctt_type = kind; 1056 1.1 darran 1057 1.1 darran return (type); 1058 1.1 darran } 1059 1.1 darran 1060 1.1 darran ctf_id_t 1061 1.1 darran ctf_add_typedef(ctf_file_t *fp, uint_t flag, const char *name, ctf_id_t ref) 1062 1.1 darran { 1063 1.1 darran ctf_dtdef_t *dtd; 1064 1.1 darran ctf_id_t type; 1065 1.4 christos ctf_file_t *fpd; 1066 1.1 darran 1067 1.4 christos fpd = fp; 1068 1.4 christos if (ref == CTF_ERR || (ctf_lookup_by_id(&fpd, ref) == NULL && 1069 1.4 christos ctf_dtd_lookup(fp, ref) == NULL)) 1070 1.1 darran return (ctf_set_errno(fp, EINVAL)); 1071 1.1 darran 1072 1.1 darran if ((type = ctf_add_generic(fp, flag, name, &dtd)) == CTF_ERR) 1073 1.1 darran return (CTF_ERR); /* errno is set for us */ 1074 1.1 darran 1075 1.8 christos dtd->dtd_data.ctt_info = LCTF_TYPE_INFO(fp, CTF_K_TYPEDEF, flag, 0); 1076 1.8 christos dtd->dtd_data.ctt_type = ref; 1077 1.4 christos ctf_ref_inc(fp, ref); 1078 1.1 darran 1079 1.1 darran return (type); 1080 1.1 darran } 1081 1.1 darran 1082 1.1 darran ctf_id_t 1083 1.1 darran ctf_add_volatile(ctf_file_t *fp, uint_t flag, ctf_id_t ref) 1084 1.1 darran { 1085 1.1 darran return (ctf_add_reftype(fp, flag, ref, CTF_K_VOLATILE)); 1086 1.1 darran } 1087 1.1 darran 1088 1.1 darran ctf_id_t 1089 1.1 darran ctf_add_const(ctf_file_t *fp, uint_t flag, ctf_id_t ref) 1090 1.1 darran { 1091 1.1 darran return (ctf_add_reftype(fp, flag, ref, CTF_K_CONST)); 1092 1.1 darran } 1093 1.1 darran 1094 1.1 darran ctf_id_t 1095 1.1 darran ctf_add_restrict(ctf_file_t *fp, uint_t flag, ctf_id_t ref) 1096 1.1 darran { 1097 1.1 darran return (ctf_add_reftype(fp, flag, ref, CTF_K_RESTRICT)); 1098 1.1 darran } 1099 1.1 darran 1100 1.1 darran int 1101 1.1 darran ctf_add_enumerator(ctf_file_t *fp, ctf_id_t enid, const char *name, int value) 1102 1.1 darran { 1103 1.1 darran ctf_dtdef_t *dtd = ctf_dtd_lookup(fp, enid); 1104 1.1 darran ctf_dmdef_t *dmd; 1105 1.1 darran 1106 1.1 darran uint_t kind, vlen, root; 1107 1.1 darran char *s; 1108 1.1 darran 1109 1.1 darran if (name == NULL) 1110 1.1 darran return (ctf_set_errno(fp, EINVAL)); 1111 1.1 darran 1112 1.1 darran if (!(fp->ctf_flags & LCTF_RDWR)) 1113 1.1 darran return (ctf_set_errno(fp, ECTF_RDONLY)); 1114 1.1 darran 1115 1.1 darran if (dtd == NULL) 1116 1.1 darran return (ctf_set_errno(fp, ECTF_BADID)); 1117 1.1 darran 1118 1.8 christos kind = LCTF_INFO_KIND(fp, dtd->dtd_data.ctt_info); 1119 1.8 christos root = LCTF_INFO_ROOT(fp, dtd->dtd_data.ctt_info); 1120 1.8 christos vlen = LCTF_INFO_VLEN(fp, dtd->dtd_data.ctt_info); 1121 1.1 darran 1122 1.1 darran if (kind != CTF_K_ENUM) 1123 1.1 darran return (ctf_set_errno(fp, ECTF_NOTENUM)); 1124 1.1 darran 1125 1.8 christos if (vlen > LCTF_MAX_VLEN(fp)) 1126 1.1 darran return (ctf_set_errno(fp, ECTF_DTFULL)); 1127 1.1 darran 1128 1.1 darran for (dmd = ctf_list_next(&dtd->dtd_u.dtu_members); 1129 1.1 darran dmd != NULL; dmd = ctf_list_next(dmd)) { 1130 1.1 darran if (strcmp(dmd->dmd_name, name) == 0) 1131 1.1 darran return (ctf_set_errno(fp, ECTF_DUPMEMBER)); 1132 1.1 darran } 1133 1.1 darran 1134 1.1 darran if ((dmd = ctf_alloc(sizeof (ctf_dmdef_t))) == NULL) 1135 1.1 darran return (ctf_set_errno(fp, EAGAIN)); 1136 1.1 darran 1137 1.1 darran if ((s = ctf_strdup(name)) == NULL) { 1138 1.1 darran ctf_free(dmd, sizeof (ctf_dmdef_t)); 1139 1.1 darran return (ctf_set_errno(fp, EAGAIN)); 1140 1.1 darran } 1141 1.1 darran 1142 1.1 darran dmd->dmd_name = s; 1143 1.1 darran dmd->dmd_type = CTF_ERR; 1144 1.1 darran dmd->dmd_offset = 0; 1145 1.1 darran dmd->dmd_value = value; 1146 1.1 darran 1147 1.8 christos dtd->dtd_data.ctt_info = LCTF_TYPE_INFO(fp, kind, root, vlen + 1); 1148 1.1 darran ctf_list_append(&dtd->dtd_u.dtu_members, dmd); 1149 1.1 darran 1150 1.1 darran fp->ctf_dtstrlen += strlen(s) + 1; 1151 1.1 darran fp->ctf_flags |= LCTF_DIRTY; 1152 1.1 darran 1153 1.1 darran return (0); 1154 1.1 darran } 1155 1.1 darran 1156 1.1 darran int 1157 1.1 darran ctf_add_member(ctf_file_t *fp, ctf_id_t souid, const char *name, ctf_id_t type) 1158 1.1 darran { 1159 1.1 darran ctf_dtdef_t *dtd = ctf_dtd_lookup(fp, souid); 1160 1.1 darran ctf_dmdef_t *dmd; 1161 1.1 darran 1162 1.1 darran ssize_t msize, malign, ssize; 1163 1.1 darran uint_t kind, vlen, root; 1164 1.1 darran char *s = NULL; 1165 1.1 darran 1166 1.1 darran if (!(fp->ctf_flags & LCTF_RDWR)) 1167 1.1 darran return (ctf_set_errno(fp, ECTF_RDONLY)); 1168 1.1 darran 1169 1.1 darran if (dtd == NULL) 1170 1.1 darran return (ctf_set_errno(fp, ECTF_BADID)); 1171 1.1 darran 1172 1.8 christos kind = LCTF_INFO_KIND(fp, dtd->dtd_data.ctt_info); 1173 1.8 christos root = LCTF_INFO_ROOT(fp, dtd->dtd_data.ctt_info); 1174 1.8 christos vlen = LCTF_INFO_VLEN(fp, dtd->dtd_data.ctt_info); 1175 1.1 darran 1176 1.1 darran if (kind != CTF_K_STRUCT && kind != CTF_K_UNION) 1177 1.1 darran return (ctf_set_errno(fp, ECTF_NOTSOU)); 1178 1.1 darran 1179 1.8 christos if (vlen > LCTF_MAX_VLEN(fp)) 1180 1.1 darran return (ctf_set_errno(fp, ECTF_DTFULL)); 1181 1.1 darran 1182 1.1 darran if (name != NULL) { 1183 1.1 darran for (dmd = ctf_list_next(&dtd->dtd_u.dtu_members); 1184 1.1 darran dmd != NULL; dmd = ctf_list_next(dmd)) { 1185 1.1 darran if (dmd->dmd_name != NULL && 1186 1.1 darran strcmp(dmd->dmd_name, name) == 0) 1187 1.1 darran return (ctf_set_errno(fp, ECTF_DUPMEMBER)); 1188 1.1 darran } 1189 1.1 darran } 1190 1.1 darran 1191 1.1 darran if ((msize = ctf_type_size(fp, type)) == CTF_ERR || 1192 1.1 darran (malign = ctf_type_align(fp, type)) == CTF_ERR) 1193 1.1 darran return (CTF_ERR); /* errno is set for us */ 1194 1.1 darran 1195 1.1 darran if ((dmd = ctf_alloc(sizeof (ctf_dmdef_t))) == NULL) 1196 1.1 darran return (ctf_set_errno(fp, EAGAIN)); 1197 1.1 darran 1198 1.1 darran if (name != NULL && (s = ctf_strdup(name)) == NULL) { 1199 1.1 darran ctf_free(dmd, sizeof (ctf_dmdef_t)); 1200 1.1 darran return (ctf_set_errno(fp, EAGAIN)); 1201 1.1 darran } 1202 1.1 darran 1203 1.1 darran dmd->dmd_name = s; 1204 1.1 darran dmd->dmd_type = type; 1205 1.1 darran dmd->dmd_value = -1; 1206 1.1 darran 1207 1.1 darran if (kind == CTF_K_STRUCT && vlen != 0) { 1208 1.1 darran ctf_dmdef_t *lmd = ctf_list_prev(&dtd->dtd_u.dtu_members); 1209 1.1 darran ctf_id_t ltype = ctf_type_resolve(fp, lmd->dmd_type); 1210 1.1 darran size_t off = lmd->dmd_offset; 1211 1.1 darran 1212 1.1 darran ctf_encoding_t linfo; 1213 1.1 darran ssize_t lsize; 1214 1.1 darran 1215 1.1 darran if (ctf_type_encoding(fp, ltype, &linfo) != CTF_ERR) 1216 1.1 darran off += linfo.cte_bits; 1217 1.1 darran else if ((lsize = ctf_type_size(fp, ltype)) != CTF_ERR) 1218 1.1 darran off += lsize * NBBY; 1219 1.1 darran 1220 1.1 darran /* 1221 1.1 darran * Round up the offset of the end of the last member to the 1222 1.1 darran * next byte boundary, convert 'off' to bytes, and then round 1223 1.1 darran * it up again to the next multiple of the alignment required 1224 1.1 darran * by the new member. Finally, convert back to bits and store 1225 1.1 darran * the result in dmd_offset. Technically we could do more 1226 1.1 darran * efficient packing if the new member is a bit-field, but 1227 1.1 darran * we're the "compiler" and ANSI says we can do as we choose. 1228 1.1 darran */ 1229 1.1 darran off = roundup(off, NBBY) / NBBY; 1230 1.1 darran off = roundup(off, MAX(malign, 1)); 1231 1.1 darran dmd->dmd_offset = off * NBBY; 1232 1.1 darran ssize = off + msize; 1233 1.1 darran } else { 1234 1.1 darran dmd->dmd_offset = 0; 1235 1.1 darran ssize = ctf_get_ctt_size(fp, &dtd->dtd_data, NULL, NULL); 1236 1.1 darran ssize = MAX(ssize, msize); 1237 1.1 darran } 1238 1.1 darran 1239 1.8 christos if (ssize > LCTF_MAX_SIZE(fp)) { 1240 1.8 christos dtd->dtd_data.ctt_size = LCTF_LSIZE_SENT(fp); 1241 1.1 darran dtd->dtd_data.ctt_lsizehi = CTF_SIZE_TO_LSIZE_HI(ssize); 1242 1.1 darran dtd->dtd_data.ctt_lsizelo = CTF_SIZE_TO_LSIZE_LO(ssize); 1243 1.1 darran } else 1244 1.8 christos dtd->dtd_data.ctt_size = ssize; 1245 1.1 darran 1246 1.8 christos dtd->dtd_data.ctt_info = LCTF_TYPE_INFO(fp, kind, root, vlen + 1); 1247 1.1 darran ctf_list_append(&dtd->dtd_u.dtu_members, dmd); 1248 1.1 darran 1249 1.1 darran if (s != NULL) 1250 1.1 darran fp->ctf_dtstrlen += strlen(s) + 1; 1251 1.1 darran 1252 1.4 christos ctf_ref_inc(fp, type); 1253 1.4 christos fp->ctf_flags |= LCTF_DIRTY; 1254 1.4 christos return (0); 1255 1.4 christos } 1256 1.4 christos 1257 1.4 christos /* 1258 1.4 christos * This removes a type from the dynamic section. This will fail if the type is 1259 1.4 christos * referenced by another type. Note that the CTF ID is never reused currently by 1260 1.4 christos * CTF. Note that if this container is a parent container then we just outright 1261 1.4 christos * refuse to remove the type. There currently is no notion of searching for the 1262 1.4 christos * ctf_dtdef_t in parent containers. If there is, then this constraint could 1263 1.4 christos * become finer grained. 1264 1.4 christos */ 1265 1.4 christos int 1266 1.4 christos ctf_delete_type(ctf_file_t *fp, ctf_id_t type) 1267 1.4 christos { 1268 1.4 christos ctf_file_t *fpd; 1269 1.4 christos ctf_dtdef_t *dtd = ctf_dtd_lookup(fp, type); 1270 1.4 christos 1271 1.4 christos if (!(fp->ctf_flags & LCTF_RDWR)) 1272 1.4 christos return (ctf_set_errno(fp, ECTF_RDONLY)); 1273 1.4 christos 1274 1.4 christos /* 1275 1.4 christos * We want to give as useful an errno as possible. That means that we 1276 1.4 christos * want to distinguish between a type which does not exist and one for 1277 1.4 christos * which the type is not dynamic. 1278 1.4 christos */ 1279 1.4 christos fpd = fp; 1280 1.4 christos if (ctf_lookup_by_id(&fpd, type) == NULL && 1281 1.4 christos ctf_dtd_lookup(fp, type) == NULL) 1282 1.4 christos return (CTF_ERR); /* errno is set for us */ 1283 1.4 christos 1284 1.4 christos if (dtd == NULL) 1285 1.4 christos return (ctf_set_errno(fp, ECTF_NOTDYN)); 1286 1.4 christos 1287 1.4 christos if (dtd->dtd_ref != 0 || fp->ctf_refcnt > 1) 1288 1.4 christos return (ctf_set_errno(fp, ECTF_REFERENCED)); 1289 1.4 christos 1290 1.4 christos ctf_dtd_delete(fp, dtd); 1291 1.1 darran fp->ctf_flags |= LCTF_DIRTY; 1292 1.1 darran return (0); 1293 1.1 darran } 1294 1.1 darran 1295 1.1 darran static int 1296 1.1 darran enumcmp(const char *name, int value, void *arg) 1297 1.1 darran { 1298 1.1 darran ctf_bundle_t *ctb = arg; 1299 1.1 darran int bvalue; 1300 1.1 darran 1301 1.1 darran return (ctf_enum_value(ctb->ctb_file, ctb->ctb_type, 1302 1.1 darran name, &bvalue) == CTF_ERR || value != bvalue); 1303 1.1 darran } 1304 1.1 darran 1305 1.1 darran static int 1306 1.1 darran enumadd(const char *name, int value, void *arg) 1307 1.1 darran { 1308 1.1 darran ctf_bundle_t *ctb = arg; 1309 1.1 darran 1310 1.1 darran return (ctf_add_enumerator(ctb->ctb_file, ctb->ctb_type, 1311 1.1 darran name, value) == CTF_ERR); 1312 1.1 darran } 1313 1.1 darran 1314 1.1 darran static int 1315 1.1 darran membadd(const char *name, ctf_id_t type, ulong_t offset, void *arg) 1316 1.1 darran { 1317 1.1 darran ctf_bundle_t *ctb = arg; 1318 1.1 darran ctf_dmdef_t *dmd; 1319 1.1 darran char *s = NULL; 1320 1.1 darran 1321 1.1 darran if ((dmd = ctf_alloc(sizeof (ctf_dmdef_t))) == NULL) 1322 1.1 darran return (ctf_set_errno(ctb->ctb_file, EAGAIN)); 1323 1.1 darran 1324 1.8 christos if (name != NULL && *name != '\0' && (s = ctf_strdup(name)) == NULL) { 1325 1.1 darran ctf_free(dmd, sizeof (ctf_dmdef_t)); 1326 1.1 darran return (ctf_set_errno(ctb->ctb_file, EAGAIN)); 1327 1.1 darran } 1328 1.1 darran 1329 1.1 darran /* 1330 1.1 darran * For now, dmd_type is copied as the src_fp's type; it is reset to an 1331 1.1 darran * equivalent dst_fp type by a final loop in ctf_add_type(), below. 1332 1.1 darran */ 1333 1.1 darran dmd->dmd_name = s; 1334 1.1 darran dmd->dmd_type = type; 1335 1.1 darran dmd->dmd_offset = offset; 1336 1.1 darran dmd->dmd_value = -1; 1337 1.1 darran 1338 1.1 darran ctf_list_append(&ctb->ctb_dtd->dtd_u.dtu_members, dmd); 1339 1.1 darran 1340 1.1 darran if (s != NULL) 1341 1.1 darran ctb->ctb_file->ctf_dtstrlen += strlen(s) + 1; 1342 1.1 darran 1343 1.1 darran ctb->ctb_file->ctf_flags |= LCTF_DIRTY; 1344 1.1 darran return (0); 1345 1.1 darran } 1346 1.1 darran 1347 1.8 christos static long 1348 1.8 christos soucmp(ctf_file_t *src_fp, ctf_id_t src_type, ctf_file_t *dst_fp, 1349 1.8 christos ctf_id_t dst_type) 1350 1.8 christos { 1351 1.8 christos const void *src_tp, *dst_tp; 1352 1.8 christos const char *src_name, *dst_name; 1353 1.8 christos ssize_t src_sz, dst_sz, src_inc, dst_inc; 1354 1.8 christos uint_t dst_kind, dst_vlen, src_kind, src_vlen, n; 1355 1.8 christos 1356 1.8 christos if ((src_type = ctf_type_resolve(src_fp, src_type)) == CTF_ERR) 1357 1.8 christos return (CTF_ERR); 1358 1.8 christos if ((dst_type = ctf_type_resolve(dst_fp, dst_type)) == CTF_ERR) 1359 1.8 christos return (CTF_ERR); 1360 1.8 christos 1361 1.8 christos if ((src_tp = ctf_lookup_by_id(&src_fp, src_type)) == NULL) 1362 1.8 christos return (CTF_ERR); 1363 1.8 christos if ((dst_tp = ctf_lookup_by_id(&dst_fp, dst_type)) == NULL) 1364 1.8 christos return (CTF_ERR); 1365 1.8 christos 1366 1.8 christos ctf_get_ctt_info(src_fp, src_tp, &src_kind, &src_vlen, NULL); 1367 1.8 christos ctf_get_ctt_info(dst_fp, dst_tp, &dst_kind, &dst_vlen, NULL); 1368 1.8 christos 1369 1.8 christos if (src_kind != dst_kind) 1370 1.8 christos return (ctf_set_errno(dst_fp, ECTF_CONFLICT)); 1371 1.8 christos if (src_kind != CTF_K_STRUCT && src_kind != CTF_K_UNION) 1372 1.8 christos return (ctf_set_errno(dst_fp, ECTF_CONFLICT)); 1373 1.8 christos if (src_vlen != dst_vlen) 1374 1.8 christos return (ctf_set_errno(dst_fp, ECTF_CONFLICT)); 1375 1.8 christos 1376 1.8 christos (void) ctf_get_ctt_size(src_fp, src_tp, &src_sz, &src_inc); 1377 1.8 christos (void) ctf_get_ctt_size(dst_fp, dst_tp, &dst_sz, &dst_inc); 1378 1.8 christos if (src_sz != dst_sz) 1379 1.8 christos return (ctf_set_errno(dst_fp, ECTF_CONFLICT)); 1380 1.8 christos 1381 1.8 christos const char *src_mp, *dst_mp; 1382 1.8 christos ulong_t src_offset, dst_offset; 1383 1.8 christos 1384 1.8 christos src_mp = (const char *)src_tp + src_inc; 1385 1.8 christos dst_mp = (const char *)dst_tp + dst_inc; 1386 1.8 christos for (n = src_vlen; n != 0; 1387 1.8 christos n--, src_mp += src_inc, dst_mp += dst_inc) { 1388 1.8 christos ctf_get_ctm_info(src_fp, src_mp, src_sz, &src_inc, NULL, 1389 1.8 christos &src_offset, &src_name); 1390 1.8 christos ctf_get_ctm_info(dst_fp, dst_mp, dst_sz, &dst_inc, NULL, 1391 1.8 christos &dst_offset, &dst_name); 1392 1.8 christos 1393 1.8 christos if (src_offset != dst_offset) 1394 1.8 christos return (ctf_set_errno(dst_fp, ECTF_CONFLICT)); 1395 1.8 christos if (strcmp(src_name, dst_name) != 0) 1396 1.8 christos return (ctf_set_errno(dst_fp, ECTF_CONFLICT)); 1397 1.8 christos } 1398 1.8 christos 1399 1.8 christos return (0); 1400 1.8 christos } 1401 1.8 christos 1402 1.1 darran /* 1403 1.1 darran * The ctf_add_type routine is used to copy a type from a source CTF container 1404 1.1 darran * to a dynamic destination container. This routine operates recursively by 1405 1.1 darran * following the source type's links and embedded member types. If the 1406 1.1 darran * destination container already contains a named type which has the same 1407 1.1 darran * attributes, then we succeed and return this type but no changes occur. 1408 1.1 darran */ 1409 1.1 darran ctf_id_t 1410 1.1 darran ctf_add_type(ctf_file_t *dst_fp, ctf_file_t *src_fp, ctf_id_t src_type) 1411 1.1 darran { 1412 1.1 darran ctf_id_t dst_type = CTF_ERR; 1413 1.1 darran uint_t dst_kind = CTF_K_UNKNOWN; 1414 1.1 darran 1415 1.8 christos const void *tp; 1416 1.1 darran const char *name; 1417 1.8 christos uint_t type, kind, flag, vlen; 1418 1.1 darran 1419 1.1 darran ctf_bundle_t src, dst; 1420 1.8 christos ctf_encoding_t src_en, main_en, dst_en; 1421 1.1 darran ctf_arinfo_t src_ar, dst_ar; 1422 1.1 darran 1423 1.1 darran ctf_dtdef_t *dtd; 1424 1.1 darran ctf_funcinfo_t ctc; 1425 1.1 darran ssize_t size; 1426 1.1 darran 1427 1.1 darran ctf_hash_t *hp; 1428 1.1 darran ctf_helem_t *hep; 1429 1.1 darran 1430 1.4 christos if (dst_fp == src_fp) 1431 1.4 christos return (src_type); 1432 1.4 christos 1433 1.1 darran if (!(dst_fp->ctf_flags & LCTF_RDWR)) 1434 1.1 darran return (ctf_set_errno(dst_fp, ECTF_RDONLY)); 1435 1.1 darran 1436 1.1 darran if ((tp = ctf_lookup_by_id(&src_fp, src_type)) == NULL) 1437 1.1 darran return (ctf_set_errno(dst_fp, ctf_errno(src_fp))); 1438 1.1 darran 1439 1.8 christos name = ctf_type_rname(src_fp, tp); 1440 1.8 christos 1441 1.8 christos ctf_get_ctt_info(src_fp, tp, &kind, &vlen, &flag); 1442 1.1 darran 1443 1.1 darran switch (kind) { 1444 1.1 darran case CTF_K_STRUCT: 1445 1.1 darran hp = &dst_fp->ctf_structs; 1446 1.1 darran break; 1447 1.1 darran case CTF_K_UNION: 1448 1.1 darran hp = &dst_fp->ctf_unions; 1449 1.1 darran break; 1450 1.1 darran case CTF_K_ENUM: 1451 1.1 darran hp = &dst_fp->ctf_enums; 1452 1.1 darran break; 1453 1.1 darran default: 1454 1.1 darran hp = &dst_fp->ctf_names; 1455 1.1 darran break; 1456 1.1 darran } 1457 1.1 darran 1458 1.1 darran /* 1459 1.1 darran * If the source type has a name and is a root type (visible at the 1460 1.1 darran * top-level scope), lookup the name in the destination container and 1461 1.1 darran * verify that it is of the same kind before we do anything else. 1462 1.1 darran */ 1463 1.1 darran if ((flag & CTF_ADD_ROOT) && name[0] != '\0' && 1464 1.1 darran (hep = ctf_hash_lookup(hp, dst_fp, name, strlen(name))) != NULL) { 1465 1.1 darran dst_type = (ctf_id_t)hep->h_type; 1466 1.1 darran dst_kind = ctf_type_kind(dst_fp, dst_type); 1467 1.1 darran } 1468 1.1 darran 1469 1.1 darran /* 1470 1.1 darran * If an identically named dst_type exists, fail with ECTF_CONFLICT 1471 1.1 darran * unless dst_type is a forward declaration and src_type is a struct, 1472 1.1 darran * union, or enum (i.e. the definition of the previous forward decl). 1473 1.1 darran */ 1474 1.4 christos if (dst_type != CTF_ERR && dst_kind != kind) { 1475 1.4 christos if (dst_kind != CTF_K_FORWARD || (kind != CTF_K_ENUM && 1476 1.4 christos kind != CTF_K_STRUCT && kind != CTF_K_UNION)) 1477 1.4 christos return (ctf_set_errno(dst_fp, ECTF_CONFLICT)); 1478 1.4 christos else 1479 1.4 christos dst_type = CTF_ERR; 1480 1.4 christos } 1481 1.1 darran 1482 1.1 darran /* 1483 1.1 darran * If the non-empty name was not found in the appropriate hash, search 1484 1.1 darran * the list of pending dynamic definitions that are not yet committed. 1485 1.1 darran * If a matching name and kind are found, assume this is the type that 1486 1.1 darran * we are looking for. This is necessary to permit ctf_add_type() to 1487 1.1 darran * operate recursively on entities such as a struct that contains a 1488 1.1 darran * pointer member that refers to the same struct type. 1489 1.4 christos * 1490 1.4 christos * In the case of integer and floating point types, we match using the 1491 1.4 christos * type encoding as well - else we may incorrectly return a bitfield 1492 1.4 christos * type, for instance. 1493 1.1 darran */ 1494 1.1 darran if (dst_type == CTF_ERR && name[0] != '\0') { 1495 1.1 darran for (dtd = ctf_list_prev(&dst_fp->ctf_dtdefs); dtd != NULL && 1496 1.8 christos LCTF_TYPE_TO_INDEX(dst_fp, dtd->dtd_type) > 1497 1.8 christos dst_fp->ctf_dtoldid; dtd = ctf_list_prev(dtd)) { 1498 1.8 christos if (LCTF_INFO_KIND(dst_fp, dtd->dtd_data.ctt_info) != 1499 1.8 christos kind || dtd->dtd_name == NULL || 1500 1.4 christos strcmp(dtd->dtd_name, name) != 0) 1501 1.4 christos continue; 1502 1.4 christos if (kind == CTF_K_INTEGER || kind == CTF_K_FLOAT) { 1503 1.4 christos if (ctf_type_encoding(src_fp, src_type, 1504 1.4 christos &src_en) != 0) 1505 1.4 christos continue; 1506 1.8 christos if (memcmp(&src_en, &dtd->dtd_u.dtu_enc, 1507 1.4 christos sizeof (ctf_encoding_t)) != 0) 1508 1.4 christos continue; 1509 1.4 christos } 1510 1.4 christos return (dtd->dtd_type); 1511 1.1 darran } 1512 1.1 darran } 1513 1.1 darran 1514 1.1 darran src.ctb_file = src_fp; 1515 1.1 darran src.ctb_type = src_type; 1516 1.1 darran src.ctb_dtd = NULL; 1517 1.1 darran 1518 1.1 darran dst.ctb_file = dst_fp; 1519 1.1 darran dst.ctb_type = dst_type; 1520 1.1 darran dst.ctb_dtd = NULL; 1521 1.1 darran 1522 1.1 darran /* 1523 1.1 darran * Now perform kind-specific processing. If dst_type is CTF_ERR, then 1524 1.1 darran * we add a new type with the same properties as src_type to dst_fp. 1525 1.1 darran * If dst_type is not CTF_ERR, then we verify that dst_type has the 1526 1.1 darran * same attributes as src_type. We recurse for embedded references. 1527 1.1 darran */ 1528 1.1 darran switch (kind) { 1529 1.1 darran case CTF_K_INTEGER: 1530 1.1 darran case CTF_K_FLOAT: 1531 1.1 darran if (ctf_type_encoding(src_fp, src_type, &src_en) != 0) 1532 1.1 darran return (ctf_set_errno(dst_fp, ctf_errno(src_fp))); 1533 1.1 darran 1534 1.8 christos /* 1535 1.8 christos * This could be a bitfield, and the CTF library assumes 1536 1.8 christos * intrinsics will appear before bitfields. Therefore, 1537 1.8 christos * try to copy over the intrinsic prior to copying the 1538 1.8 christos * bitfield. 1539 1.8 christos */ 1540 1.8 christos if (dst_type == CTF_ERR && name[0] != '\0' && 1541 1.8 christos (hep = ctf_hash_lookup(&src_fp->ctf_names, src_fp, name, 1542 1.8 christos strlen(name))) != NULL && 1543 1.8 christos src_type != (ctf_id_t)hep->h_type) { 1544 1.8 christos if (ctf_type_encoding(src_fp, (ctf_id_t)hep->h_type, 1545 1.8 christos &main_en) != 0) { 1546 1.8 christos return (ctf_set_errno(dst_fp, 1547 1.8 christos ctf_errno(src_fp))); 1548 1.8 christos } 1549 1.8 christos if (memcmp(&src_en, &main_en, sizeof (ctf_encoding_t)) && 1550 1.8 christos ctf_add_type(dst_fp, src_fp, 1551 1.8 christos (ctf_id_t)hep->h_type) == CTF_ERR) 1552 1.8 christos return (CTF_ERR); /* errno is set for us */ 1553 1.8 christos } 1554 1.8 christos 1555 1.1 darran if (dst_type != CTF_ERR) { 1556 1.1 darran if (ctf_type_encoding(dst_fp, dst_type, &dst_en) != 0) 1557 1.1 darran return (CTF_ERR); /* errno is set for us */ 1558 1.1 darran 1559 1.8 christos if (memcmp(&src_en, &dst_en, sizeof (ctf_encoding_t))) 1560 1.1 darran return (ctf_set_errno(dst_fp, ECTF_CONFLICT)); 1561 1.1 darran 1562 1.1 darran } else if (kind == CTF_K_INTEGER) { 1563 1.1 darran dst_type = ctf_add_integer(dst_fp, flag, name, &src_en); 1564 1.1 darran } else 1565 1.1 darran dst_type = ctf_add_float(dst_fp, flag, name, &src_en); 1566 1.1 darran break; 1567 1.1 darran 1568 1.1 darran case CTF_K_POINTER: 1569 1.1 darran case CTF_K_VOLATILE: 1570 1.1 darran case CTF_K_CONST: 1571 1.1 darran case CTF_K_RESTRICT: 1572 1.1 darran src_type = ctf_type_reference(src_fp, src_type); 1573 1.1 darran src_type = ctf_add_type(dst_fp, src_fp, src_type); 1574 1.1 darran 1575 1.1 darran if (src_type == CTF_ERR) 1576 1.1 darran return (CTF_ERR); /* errno is set for us */ 1577 1.1 darran 1578 1.1 darran dst_type = ctf_add_reftype(dst_fp, flag, src_type, kind); 1579 1.1 darran break; 1580 1.1 darran 1581 1.1 darran case CTF_K_ARRAY: 1582 1.1 darran if (ctf_array_info(src_fp, src_type, &src_ar) == CTF_ERR) 1583 1.1 darran return (ctf_set_errno(dst_fp, ctf_errno(src_fp))); 1584 1.1 darran 1585 1.1 darran src_ar.ctr_contents = 1586 1.1 darran ctf_add_type(dst_fp, src_fp, src_ar.ctr_contents); 1587 1.1 darran src_ar.ctr_index = 1588 1.1 darran ctf_add_type(dst_fp, src_fp, src_ar.ctr_index); 1589 1.1 darran src_ar.ctr_nelems = src_ar.ctr_nelems; 1590 1.1 darran 1591 1.1 darran if (src_ar.ctr_contents == CTF_ERR || 1592 1.1 darran src_ar.ctr_index == CTF_ERR) 1593 1.1 darran return (CTF_ERR); /* errno is set for us */ 1594 1.1 darran 1595 1.1 darran if (dst_type != CTF_ERR) { 1596 1.1 darran if (ctf_array_info(dst_fp, dst_type, &dst_ar) != 0) 1597 1.1 darran return (CTF_ERR); /* errno is set for us */ 1598 1.1 darran 1599 1.8 christos if (memcmp(&src_ar, &dst_ar, sizeof (ctf_arinfo_t))) 1600 1.1 darran return (ctf_set_errno(dst_fp, ECTF_CONFLICT)); 1601 1.1 darran } else 1602 1.1 darran dst_type = ctf_add_array(dst_fp, flag, &src_ar); 1603 1.1 darran break; 1604 1.1 darran 1605 1.1 darran case CTF_K_FUNCTION: 1606 1.8 christos ctf_get_ctt_index(src_fp, tp, NULL, &type, NULL); 1607 1.8 christos ctc.ctc_return = ctf_add_type(dst_fp, src_fp, type); 1608 1.1 darran ctc.ctc_argc = 0; 1609 1.1 darran ctc.ctc_flags = 0; 1610 1.1 darran 1611 1.1 darran if (ctc.ctc_return == CTF_ERR) 1612 1.1 darran return (CTF_ERR); /* errno is set for us */ 1613 1.1 darran 1614 1.1 darran dst_type = ctf_add_function(dst_fp, flag, &ctc, NULL); 1615 1.1 darran break; 1616 1.1 darran 1617 1.1 darran case CTF_K_STRUCT: 1618 1.1 darran case CTF_K_UNION: { 1619 1.1 darran ctf_dmdef_t *dmd; 1620 1.1 darran int errs = 0; 1621 1.1 darran 1622 1.1 darran if (dst_type != CTF_ERR && dst_kind != CTF_K_FORWARD) { 1623 1.8 christos /* 1624 1.8 christos * Compare the sizes and fields of the two types. 1625 1.8 christos * The field comparisons only check the names and 1626 1.8 christos * offsets, so this is not perfect but is good enough 1627 1.8 christos * for scenarios that we care about. 1628 1.8 christos */ 1629 1.8 christos if (soucmp(src_fp, src_type, dst_fp, dst_type) != 0) 1630 1.8 christos return (CTF_ERR); /* errno is set for us */ 1631 1.1 darran break; 1632 1.1 darran } 1633 1.1 darran 1634 1.1 darran /* 1635 1.1 darran * Unlike the other cases, copying structs and unions is done 1636 1.1 darran * manually so as to avoid repeated lookups in ctf_add_member 1637 1.1 darran * and to ensure the exact same member offsets as in src_type. 1638 1.1 darran */ 1639 1.1 darran dst_type = ctf_add_generic(dst_fp, flag, name, &dtd); 1640 1.1 darran if (dst_type == CTF_ERR) 1641 1.1 darran return (CTF_ERR); /* errno is set for us */ 1642 1.1 darran 1643 1.1 darran dst.ctb_type = dst_type; 1644 1.1 darran dst.ctb_dtd = dtd; 1645 1.1 darran 1646 1.1 darran if (ctf_member_iter(src_fp, src_type, membadd, &dst) != 0) 1647 1.1 darran errs++; /* increment errs and fail at bottom of case */ 1648 1.1 darran 1649 1.8 christos if ((size = ctf_type_size(src_fp, src_type)) > 1650 1.8 christos LCTF_MAX_SIZE(src_fp)) { 1651 1.8 christos dtd->dtd_data.ctt_size = LCTF_LSIZE_SENT(dst_fp); 1652 1.1 darran dtd->dtd_data.ctt_lsizehi = CTF_SIZE_TO_LSIZE_HI(size); 1653 1.1 darran dtd->dtd_data.ctt_lsizelo = CTF_SIZE_TO_LSIZE_LO(size); 1654 1.1 darran } else 1655 1.8 christos dtd->dtd_data.ctt_size = size; 1656 1.1 darran 1657 1.8 christos dtd->dtd_data.ctt_info = LCTF_TYPE_INFO(dst_fp, kind, flag, 1658 1.8 christos vlen); 1659 1.1 darran 1660 1.1 darran /* 1661 1.1 darran * Make a final pass through the members changing each dmd_type 1662 1.1 darran * (a src_fp type) to an equivalent type in dst_fp. We pass 1663 1.1 darran * through all members, leaving any that fail set to CTF_ERR. 1664 1.1 darran */ 1665 1.1 darran for (dmd = ctf_list_next(&dtd->dtd_u.dtu_members); 1666 1.1 darran dmd != NULL; dmd = ctf_list_next(dmd)) { 1667 1.1 darran if ((dmd->dmd_type = ctf_add_type(dst_fp, src_fp, 1668 1.1 darran dmd->dmd_type)) == CTF_ERR) 1669 1.1 darran errs++; 1670 1.1 darran } 1671 1.1 darran 1672 1.1 darran if (errs) 1673 1.1 darran return (CTF_ERR); /* errno is set for us */ 1674 1.4 christos 1675 1.4 christos /* 1676 1.4 christos * Now that we know that we can't fail, we go through and bump 1677 1.4 christos * all the reference counts on the member types. 1678 1.4 christos */ 1679 1.4 christos for (dmd = ctf_list_next(&dtd->dtd_u.dtu_members); 1680 1.4 christos dmd != NULL; dmd = ctf_list_next(dmd)) 1681 1.4 christos ctf_ref_inc(dst_fp, dmd->dmd_type); 1682 1.1 darran break; 1683 1.1 darran } 1684 1.1 darran 1685 1.1 darran case CTF_K_ENUM: 1686 1.1 darran if (dst_type != CTF_ERR && dst_kind != CTF_K_FORWARD) { 1687 1.1 darran if (ctf_enum_iter(src_fp, src_type, enumcmp, &dst) || 1688 1.1 darran ctf_enum_iter(dst_fp, dst_type, enumcmp, &src)) 1689 1.1 darran return (ctf_set_errno(dst_fp, ECTF_CONFLICT)); 1690 1.1 darran } else { 1691 1.1 darran dst_type = ctf_add_enum(dst_fp, flag, name); 1692 1.1 darran if ((dst.ctb_type = dst_type) == CTF_ERR || 1693 1.1 darran ctf_enum_iter(src_fp, src_type, enumadd, &dst)) 1694 1.1 darran return (CTF_ERR); /* errno is set for us */ 1695 1.1 darran } 1696 1.1 darran break; 1697 1.1 darran 1698 1.1 darran case CTF_K_FORWARD: 1699 1.1 darran if (dst_type == CTF_ERR) { 1700 1.1 darran dst_type = ctf_add_forward(dst_fp, 1701 1.1 darran flag, name, CTF_K_STRUCT); /* assume STRUCT */ 1702 1.1 darran } 1703 1.1 darran break; 1704 1.1 darran 1705 1.1 darran case CTF_K_TYPEDEF: 1706 1.1 darran src_type = ctf_type_reference(src_fp, src_type); 1707 1.1 darran src_type = ctf_add_type(dst_fp, src_fp, src_type); 1708 1.1 darran 1709 1.1 darran if (src_type == CTF_ERR) 1710 1.1 darran return (CTF_ERR); /* errno is set for us */ 1711 1.1 darran 1712 1.1 darran /* 1713 1.1 darran * If dst_type is not CTF_ERR at this point, we should check if 1714 1.1 darran * ctf_type_reference(dst_fp, dst_type) != src_type and if so 1715 1.1 darran * fail with ECTF_CONFLICT. However, this causes problems with 1716 1.1 darran * <sys/types.h> typedefs that vary based on things like if 1717 1.1 darran * _ILP32x then pid_t is int otherwise long. We therefore omit 1718 1.1 darran * this check and assume that if the identically named typedef 1719 1.1 darran * already exists in dst_fp, it is correct or equivalent. 1720 1.1 darran */ 1721 1.1 darran if (dst_type == CTF_ERR) { 1722 1.1 darran dst_type = ctf_add_typedef(dst_fp, flag, 1723 1.1 darran name, src_type); 1724 1.1 darran } 1725 1.1 darran break; 1726 1.1 darran 1727 1.1 darran default: 1728 1.1 darran return (ctf_set_errno(dst_fp, ECTF_CORRUPT)); 1729 1.1 darran } 1730 1.1 darran 1731 1.1 darran return (dst_type); 1732 1.1 darran } 1733