1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 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 * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #pragma ident "%Z%%M% %I% %E% SMI" 28 29 #include <sys/sysmacros.h> 30 #include <sys/param.h> 31 #include <sys/mman.h> 32 #include <ctf_impl.h> 33 34 /* 35 * This static string is used as the template for initially populating a 36 * dynamic container's string table. We always store \0 in the first byte, 37 * and we use the generic string "PARENT" to mark this container's parent 38 * if one is associated with the container using ctf_import(). 39 */ 40 static const char _CTF_STRTAB_TEMPLATE[] = "\0PARENT"; 41 42 /* 43 * To create an empty CTF container, we just declare a zeroed header and call 44 * ctf_bufopen() on it. If ctf_bufopen succeeds, we mark the new container r/w 45 * and initialize the dynamic members. We set dtstrlen to 1 to reserve the 46 * first byte of the string table for a \0 byte, and we start assigning type 47 * IDs at 1 because type ID 0 is used as a sentinel. 48 */ 49 ctf_file_t * 50 ctf_create(int *errp) 51 { 52 static const ctf_header_t hdr = { { CTF_MAGIC, CTF_VERSION, 0 } }; 53 54 ctf_sect_t cts; 55 ctf_file_t *fp; 56 57 cts.cts_name = _CTF_SECTION; 58 cts.cts_type = SHT_PROGBITS; 59 cts.cts_flags = 0; 60 cts.cts_data = &hdr; 61 cts.cts_size = sizeof (hdr); 62 cts.cts_entsize = 1; 63 cts.cts_offset = 0; 64 65 if ((fp = ctf_bufopen(&cts, NULL, NULL, errp)) != NULL) { 66 fp->ctf_flags |= LCTF_RDWR; 67 fp->ctf_dtstrlen = sizeof (_CTF_STRTAB_TEMPLATE); 68 fp->ctf_dtnextid = 1; 69 fp->ctf_dtoldid = 0; 70 } 71 72 return (fp); 73 } 74 75 static uchar_t * 76 ctf_copy_smembers(ctf_dtdef_t *dtd, uint_t soff, uchar_t *t) 77 { 78 ctf_dmdef_t *dmd = ctf_list_next(&dtd->dtd_u.dtu_members); 79 ctf_member_t ctm; 80 81 for (; dmd != NULL; dmd = ctf_list_next(dmd)) { 82 if (dmd->dmd_name) { 83 ctm.ctm_name = soff; 84 soff += strlen(dmd->dmd_name) + 1; 85 } else 86 ctm.ctm_name = 0; 87 88 ctm.ctm_type = (ushort_t)dmd->dmd_type; 89 ctm.ctm_offset = (ushort_t)dmd->dmd_offset; 90 91 bcopy(&ctm, t, sizeof (ctm)); 92 t += sizeof (ctm); 93 } 94 95 return (t); 96 } 97 98 static uchar_t * 99 ctf_copy_lmembers(ctf_dtdef_t *dtd, uint_t soff, uchar_t *t) 100 { 101 ctf_dmdef_t *dmd = ctf_list_next(&dtd->dtd_u.dtu_members); 102 ctf_lmember_t ctlm; 103 104 for (; dmd != NULL; dmd = ctf_list_next(dmd)) { 105 if (dmd->dmd_name) { 106 ctlm.ctlm_name = soff; 107 soff += strlen(dmd->dmd_name) + 1; 108 } else 109 ctlm.ctlm_name = 0; 110 111 ctlm.ctlm_type = (ushort_t)dmd->dmd_type; 112 ctlm.ctlm_pad = 0; 113 ctlm.ctlm_offsethi = CTF_OFFSET_TO_LMEMHI(dmd->dmd_offset); 114 ctlm.ctlm_offsetlo = CTF_OFFSET_TO_LMEMLO(dmd->dmd_offset); 115 116 bcopy(&ctlm, t, sizeof (ctlm)); 117 t += sizeof (ctlm); 118 } 119 120 return (t); 121 } 122 123 static uchar_t * 124 ctf_copy_emembers(ctf_dtdef_t *dtd, uint_t soff, uchar_t *t) 125 { 126 ctf_dmdef_t *dmd = ctf_list_next(&dtd->dtd_u.dtu_members); 127 ctf_enum_t cte; 128 129 for (; dmd != NULL; dmd = ctf_list_next(dmd)) { 130 cte.cte_name = soff; 131 cte.cte_value = dmd->dmd_value; 132 soff += strlen(dmd->dmd_name) + 1; 133 bcopy(&cte, t, sizeof (cte)); 134 t += sizeof (cte); 135 } 136 137 return (t); 138 } 139 140 static uchar_t * 141 ctf_copy_membnames(ctf_dtdef_t *dtd, uchar_t *s) 142 { 143 ctf_dmdef_t *dmd = ctf_list_next(&dtd->dtd_u.dtu_members); 144 size_t len; 145 146 for (; dmd != NULL; dmd = ctf_list_next(dmd)) { 147 if (dmd->dmd_name == NULL) 148 continue; /* skip anonymous members */ 149 len = strlen(dmd->dmd_name) + 1; 150 bcopy(dmd->dmd_name, s, len); 151 s += len; 152 } 153 154 return (s); 155 } 156 157 /* 158 * If the specified CTF container is writable and has been modified, reload 159 * this container with the updated type definitions. In order to make this 160 * code and the rest of libctf as simple as possible, we perform updates by 161 * taking the dynamic type definitions and creating an in-memory CTF file 162 * containing the definitions, and then call ctf_bufopen() on it. This not 163 * only leverages ctf_bufopen(), but also avoids having to bifurcate the rest 164 * of the library code with different lookup paths for static and dynamic 165 * type definitions. We are therefore optimizing greatly for lookup over 166 * update, which we assume will be an uncommon operation. We perform one 167 * extra trick here for the benefit of callers and to keep our code simple: 168 * ctf_bufopen() will return a new ctf_file_t, but we want to keep the fp 169 * constant for the caller, so after ctf_bufopen() returns, we use bcopy to 170 * swap the interior of the old and new ctf_file_t's, and then free the old. 171 */ 172 int 173 ctf_update(ctf_file_t *fp) 174 { 175 ctf_file_t ofp, *nfp; 176 ctf_header_t hdr; 177 ctf_dtdef_t *dtd; 178 ctf_sect_t cts; 179 180 uchar_t *s, *s0, *t; 181 size_t size; 182 void *buf; 183 int err; 184 185 if (!(fp->ctf_flags & LCTF_RDWR)) 186 return (ctf_set_errno(fp, ECTF_RDONLY)); 187 188 if (!(fp->ctf_flags & LCTF_DIRTY)) 189 return (0); /* no update required */ 190 191 /* 192 * Fill in an initial CTF header. We will leave the label, object, 193 * and function sections empty and only output a header, type section, 194 * and string table. The type section begins at a 4-byte aligned 195 * boundary past the CTF header itself (at relative offset zero). 196 */ 197 bzero(&hdr, sizeof (hdr)); 198 hdr.cth_magic = CTF_MAGIC; 199 hdr.cth_version = CTF_VERSION; 200 201 if (fp->ctf_flags & LCTF_CHILD) 202 hdr.cth_parname = 1; /* i.e. _CTF_STRTAB_TEMPLATE[1] */ 203 204 /* 205 * Iterate through the dynamic type definition list and compute the 206 * size of the CTF type section we will need to generate. 207 */ 208 for (size = 0, dtd = ctf_list_next(&fp->ctf_dtdefs); 209 dtd != NULL; dtd = ctf_list_next(dtd)) { 210 211 uint_t kind = CTF_INFO_KIND(dtd->dtd_data.ctt_info); 212 uint_t vlen = CTF_INFO_VLEN(dtd->dtd_data.ctt_info); 213 214 if (dtd->dtd_data.ctt_size != CTF_LSIZE_SENT) 215 size += sizeof (ctf_stype_t); 216 else 217 size += sizeof (ctf_type_t); 218 219 switch (kind) { 220 case CTF_K_INTEGER: 221 case CTF_K_FLOAT: 222 size += sizeof (uint_t); 223 break; 224 case CTF_K_ARRAY: 225 size += sizeof (ctf_array_t); 226 break; 227 case CTF_K_FUNCTION: 228 size += sizeof (ushort_t) * (vlen + (vlen & 1)); 229 break; 230 case CTF_K_STRUCT: 231 case CTF_K_UNION: 232 if (dtd->dtd_data.ctt_size < CTF_LSTRUCT_THRESH) 233 size += sizeof (ctf_member_t) * vlen; 234 else 235 size += sizeof (ctf_lmember_t) * vlen; 236 break; 237 case CTF_K_ENUM: 238 size += sizeof (ctf_enum_t) * vlen; 239 break; 240 } 241 } 242 243 /* 244 * Fill in the string table offset and size, compute the size of the 245 * entire CTF buffer we need, and then allocate a new buffer and 246 * bcopy the finished header to the start of the buffer. 247 */ 248 hdr.cth_stroff = hdr.cth_typeoff + size; 249 hdr.cth_strlen = fp->ctf_dtstrlen; 250 size = sizeof (ctf_header_t) + hdr.cth_stroff + hdr.cth_strlen; 251 252 if ((buf = ctf_data_alloc(size)) == MAP_FAILED) 253 return (ctf_set_errno(fp, EAGAIN)); 254 255 bcopy(&hdr, buf, sizeof (ctf_header_t)); 256 t = (uchar_t *)buf + sizeof (ctf_header_t); 257 s = s0 = (uchar_t *)buf + sizeof (ctf_header_t) + hdr.cth_stroff; 258 259 bcopy(_CTF_STRTAB_TEMPLATE, s, sizeof (_CTF_STRTAB_TEMPLATE)); 260 s += sizeof (_CTF_STRTAB_TEMPLATE); 261 262 /* 263 * We now take a final lap through the dynamic type definition list and 264 * copy the appropriate type records and strings to the output buffer. 265 */ 266 for (dtd = ctf_list_next(&fp->ctf_dtdefs); 267 dtd != NULL; dtd = ctf_list_next(dtd)) { 268 269 uint_t kind = CTF_INFO_KIND(dtd->dtd_data.ctt_info); 270 uint_t vlen = CTF_INFO_VLEN(dtd->dtd_data.ctt_info); 271 272 ctf_array_t cta; 273 uint_t encoding; 274 size_t len; 275 276 if (dtd->dtd_name != NULL) { 277 dtd->dtd_data.ctt_name = (uint_t)(s - s0); 278 len = strlen(dtd->dtd_name) + 1; 279 bcopy(dtd->dtd_name, s, len); 280 s += len; 281 } else 282 dtd->dtd_data.ctt_name = 0; 283 284 if (dtd->dtd_data.ctt_size != CTF_LSIZE_SENT) 285 len = sizeof (ctf_stype_t); 286 else 287 len = sizeof (ctf_type_t); 288 289 bcopy(&dtd->dtd_data, t, len); 290 t += len; 291 292 switch (kind) { 293 case CTF_K_INTEGER: 294 case CTF_K_FLOAT: 295 if (kind == CTF_K_INTEGER) { 296 encoding = CTF_INT_DATA( 297 dtd->dtd_u.dtu_enc.cte_format, 298 dtd->dtd_u.dtu_enc.cte_offset, 299 dtd->dtd_u.dtu_enc.cte_bits); 300 } else { 301 encoding = CTF_FP_DATA( 302 dtd->dtd_u.dtu_enc.cte_format, 303 dtd->dtd_u.dtu_enc.cte_offset, 304 dtd->dtd_u.dtu_enc.cte_bits); 305 } 306 bcopy(&encoding, t, sizeof (encoding)); 307 t += sizeof (encoding); 308 break; 309 310 case CTF_K_ARRAY: 311 cta.cta_contents = (ushort_t) 312 dtd->dtd_u.dtu_arr.ctr_contents; 313 cta.cta_index = (ushort_t) 314 dtd->dtd_u.dtu_arr.ctr_index; 315 cta.cta_nelems = dtd->dtd_u.dtu_arr.ctr_nelems; 316 bcopy(&cta, t, sizeof (cta)); 317 t += sizeof (cta); 318 break; 319 320 case CTF_K_FUNCTION: { 321 ushort_t *argv = (ushort_t *)(uintptr_t)t; 322 uint_t argc; 323 324 for (argc = 0; argc < vlen; argc++) 325 *argv++ = (ushort_t)dtd->dtd_u.dtu_argv[argc]; 326 327 if (vlen & 1) 328 *argv++ = 0; /* pad to 4-byte boundary */ 329 330 t = (uchar_t *)argv; 331 break; 332 } 333 334 case CTF_K_STRUCT: 335 case CTF_K_UNION: 336 if (dtd->dtd_data.ctt_size < CTF_LSTRUCT_THRESH) 337 t = ctf_copy_smembers(dtd, (uint_t)(s - s0), t); 338 else 339 t = ctf_copy_lmembers(dtd, (uint_t)(s - s0), t); 340 s = ctf_copy_membnames(dtd, s); 341 break; 342 343 case CTF_K_ENUM: 344 t = ctf_copy_emembers(dtd, (uint_t)(s - s0), t); 345 s = ctf_copy_membnames(dtd, s); 346 break; 347 } 348 } 349 350 /* 351 * Finally, we are ready to ctf_bufopen() the new container. If this 352 * is successful, we then switch nfp and fp and free the old container. 353 */ 354 ctf_data_protect(buf, size); 355 cts.cts_name = _CTF_SECTION; 356 cts.cts_type = SHT_PROGBITS; 357 cts.cts_flags = 0; 358 cts.cts_data = buf; 359 cts.cts_size = size; 360 cts.cts_entsize = 1; 361 cts.cts_offset = 0; 362 363 if ((nfp = ctf_bufopen(&cts, NULL, NULL, &err)) == NULL) { 364 ctf_data_free(buf, size); 365 return (ctf_set_errno(fp, err)); 366 } 367 368 (void) ctf_setmodel(nfp, ctf_getmodel(fp)); 369 (void) ctf_import(nfp, fp->ctf_parent); 370 371 nfp->ctf_refcnt = fp->ctf_refcnt; 372 nfp->ctf_flags |= fp->ctf_flags & ~LCTF_DIRTY; 373 nfp->ctf_data.cts_data = NULL; /* force ctf_data_free() on close */ 374 nfp->ctf_dtdefs = fp->ctf_dtdefs; 375 nfp->ctf_dtstrlen = fp->ctf_dtstrlen; 376 nfp->ctf_dtnextid = fp->ctf_dtnextid; 377 nfp->ctf_dtoldid = fp->ctf_dtnextid - 1; 378 nfp->ctf_specific = fp->ctf_specific; 379 380 bzero(&fp->ctf_dtdefs, sizeof (ctf_list_t)); 381 bcopy(fp, &ofp, sizeof (ctf_file_t)); 382 bcopy(nfp, fp, sizeof (ctf_file_t)); 383 bcopy(&ofp, nfp, sizeof (ctf_file_t)); 384 385 /* 386 * Initialize the ctf_lookup_by_name top-level dictionary. We keep an 387 * array of type name prefixes and the corresponding ctf_hash to use. 388 * NOTE: This code must be kept in sync with the code in ctf_bufopen(). 389 */ 390 fp->ctf_lookups[0].ctl_hash = &fp->ctf_structs; 391 fp->ctf_lookups[1].ctl_hash = &fp->ctf_unions; 392 fp->ctf_lookups[2].ctl_hash = &fp->ctf_enums; 393 fp->ctf_lookups[3].ctl_hash = &fp->ctf_names; 394 395 nfp->ctf_refcnt = 1; /* force nfp to be freed */ 396 ctf_close(nfp); 397 398 return (0); 399 } 400 401 /* 402 * Discard all of the dynamic type definitions that have been added to the 403 * container since the last call to ctf_update(). We locate such types by 404 * scanning the list and deleting elements that have type IDs greater than 405 * ctf_dtoldid, which is set by ctf_update(), above. 406 */ 407 int 408 ctf_discard(ctf_file_t *fp) 409 { 410 ctf_dtdef_t *dtd, *ntd; 411 ctf_dmdef_t *dmd, *nmd; 412 size_t len; 413 414 if (!(fp->ctf_flags & LCTF_RDWR)) 415 return (ctf_set_errno(fp, ECTF_RDONLY)); 416 417 if (!(fp->ctf_flags & LCTF_DIRTY)) 418 return (0); /* no update required */ 419 420 for (dtd = ctf_list_next(&fp->ctf_dtdefs); dtd != NULL; dtd = ntd) { 421 if (dtd->dtd_type <= fp->ctf_dtoldid) 422 continue; /* skip types that have been committed */ 423 424 switch (CTF_INFO_KIND(dtd->dtd_data.ctt_info)) { 425 case CTF_K_STRUCT: 426 case CTF_K_UNION: 427 case CTF_K_ENUM: 428 for (dmd = ctf_list_next(&dtd->dtd_u.dtu_members); 429 dmd != NULL; dmd = nmd) { 430 if (dmd->dmd_name != NULL) { 431 len = strlen(dmd->dmd_name) + 1; 432 ctf_free(dmd->dmd_name, len); 433 fp->ctf_dtstrlen -= len; 434 } 435 nmd = ctf_list_next(dmd); 436 ctf_free(dmd, sizeof (ctf_dmdef_t)); 437 } 438 break; 439 case CTF_K_FUNCTION: 440 ctf_free(dtd->dtd_u.dtu_argv, sizeof (ctf_id_t) * 441 CTF_INFO_VLEN(dtd->dtd_data.ctt_info)); 442 break; 443 } 444 445 if (dtd->dtd_name) { 446 len = strlen(dtd->dtd_name) + 1; 447 ctf_free(dtd->dtd_name, len); 448 fp->ctf_dtstrlen -= len; 449 } 450 451 ntd = ctf_list_next(dtd); 452 ctf_list_delete(&fp->ctf_dtdefs, dtd); 453 ctf_free(dtd, sizeof (ctf_dtdef_t)); 454 } 455 456 fp->ctf_dtnextid = fp->ctf_dtoldid + 1; 457 fp->ctf_flags &= ~LCTF_DIRTY; 458 459 return (0); 460 } 461 462 static ctf_id_t 463 ctf_add_generic(ctf_file_t *fp, uint_t flag, const char *name, ctf_dtdef_t **rp) 464 { 465 ctf_dtdef_t *dtd; 466 ctf_id_t type; 467 char *s = NULL; 468 469 if (flag != CTF_ADD_NONROOT && flag != CTF_ADD_ROOT) 470 return (ctf_set_errno(fp, EINVAL)); 471 472 if (!(fp->ctf_flags & LCTF_RDWR)) 473 return (ctf_set_errno(fp, ECTF_RDONLY)); 474 475 if (CTF_INDEX_TO_TYPE(fp->ctf_dtnextid, 1) > CTF_MAX_TYPE) 476 return (ctf_set_errno(fp, ECTF_FULL)); 477 478 if ((dtd = ctf_alloc(sizeof (ctf_dtdef_t))) == NULL) 479 return (ctf_set_errno(fp, EAGAIN)); 480 481 if (name != NULL && (s = ctf_strdup(name)) == NULL) { 482 ctf_free(dtd, sizeof (ctf_dtdef_t)); 483 return (ctf_set_errno(fp, EAGAIN)); 484 } 485 486 type = fp->ctf_dtnextid++; 487 type = CTF_INDEX_TO_TYPE(type, (fp->ctf_flags & LCTF_CHILD)); 488 489 bzero(dtd, sizeof (ctf_dtdef_t)); 490 dtd->dtd_name = s; 491 dtd->dtd_type = type; 492 493 if (s != NULL) 494 fp->ctf_dtstrlen += strlen(s) + 1; 495 496 ctf_list_append(&fp->ctf_dtdefs, dtd); 497 fp->ctf_flags |= LCTF_DIRTY; 498 499 *rp = dtd; 500 return (type); 501 } 502 503 /* 504 * When encoding integer sizes, we want to convert a byte count in the range 505 * 1-8 to the closest power of 2 (e.g. 3->4, 5->8, etc). The clp2() function 506 * is a clever implementation from "Hacker's Delight" by Henry Warren, Jr. 507 */ 508 static size_t 509 clp2(size_t x) 510 { 511 x--; 512 513 x |= (x >> 1); 514 x |= (x >> 2); 515 x |= (x >> 4); 516 x |= (x >> 8); 517 x |= (x >> 16); 518 519 return (x + 1); 520 } 521 522 static ctf_id_t 523 ctf_add_encoded(ctf_file_t *fp, uint_t flag, 524 const char *name, const ctf_encoding_t *ep, uint_t kind) 525 { 526 ctf_dtdef_t *dtd; 527 ctf_id_t type; 528 529 if (ep == NULL) 530 return (ctf_set_errno(fp, EINVAL)); 531 532 if ((type = ctf_add_generic(fp, flag, name, &dtd)) == CTF_ERR) 533 return (CTF_ERR); /* errno is set for us */ 534 535 dtd->dtd_data.ctt_info = CTF_TYPE_INFO(kind, flag, 0); 536 dtd->dtd_data.ctt_size = clp2(P2ROUNDUP(ep->cte_bits, NBBY) / NBBY); 537 dtd->dtd_u.dtu_enc = *ep; 538 539 return (type); 540 } 541 542 static ctf_id_t 543 ctf_add_reftype(ctf_file_t *fp, uint_t flag, ctf_id_t ref, uint_t kind) 544 { 545 ctf_dtdef_t *dtd; 546 ctf_id_t type; 547 548 if (ref == CTF_ERR || ref < 0 || ref > CTF_MAX_TYPE) 549 return (ctf_set_errno(fp, EINVAL)); 550 551 if ((type = ctf_add_generic(fp, flag, NULL, &dtd)) == CTF_ERR) 552 return (CTF_ERR); /* errno is set for us */ 553 554 dtd->dtd_data.ctt_info = CTF_TYPE_INFO(kind, flag, 0); 555 dtd->dtd_data.ctt_type = (ushort_t)ref; 556 557 return (type); 558 } 559 560 ctf_id_t 561 ctf_add_integer(ctf_file_t *fp, uint_t flag, 562 const char *name, const ctf_encoding_t *ep) 563 { 564 return (ctf_add_encoded(fp, flag, name, ep, CTF_K_INTEGER)); 565 } 566 567 ctf_id_t 568 ctf_add_float(ctf_file_t *fp, uint_t flag, 569 const char *name, const ctf_encoding_t *ep) 570 { 571 return (ctf_add_encoded(fp, flag, name, ep, CTF_K_FLOAT)); 572 } 573 574 ctf_id_t 575 ctf_add_pointer(ctf_file_t *fp, uint_t flag, ctf_id_t ref) 576 { 577 return (ctf_add_reftype(fp, flag, ref, CTF_K_POINTER)); 578 } 579 580 ctf_id_t 581 ctf_add_array(ctf_file_t *fp, uint_t flag, const ctf_arinfo_t *arp) 582 { 583 ctf_dtdef_t *dtd; 584 ctf_id_t type; 585 586 if (arp == NULL) 587 return (ctf_set_errno(fp, EINVAL)); 588 589 if ((type = ctf_add_generic(fp, flag, NULL, &dtd)) == CTF_ERR) 590 return (CTF_ERR); /* errno is set for us */ 591 592 dtd->dtd_data.ctt_info = CTF_TYPE_INFO(CTF_K_ARRAY, flag, 0); 593 dtd->dtd_data.ctt_size = 0; 594 dtd->dtd_u.dtu_arr = *arp; 595 596 return (type); 597 } 598 599 int 600 ctf_set_array(ctf_file_t *fp, ctf_id_t type, const ctf_arinfo_t *arp) 601 { 602 ctf_dtdef_t *dtd; 603 604 if (!(fp->ctf_flags & LCTF_RDWR)) 605 return (ctf_set_errno(fp, ECTF_RDONLY)); 606 607 for (dtd = ctf_list_next(&fp->ctf_dtdefs); 608 dtd != NULL; dtd = ctf_list_next(dtd)) { 609 if (dtd->dtd_type == type) 610 break; 611 } 612 613 if (dtd == NULL || CTF_INFO_KIND(dtd->dtd_data.ctt_info) != CTF_K_ARRAY) 614 return (ctf_set_errno(fp, ECTF_BADID)); 615 616 fp->ctf_flags |= LCTF_DIRTY; 617 dtd->dtd_u.dtu_arr = *arp; 618 619 return (0); 620 } 621 622 ctf_id_t 623 ctf_add_function(ctf_file_t *fp, uint_t flag, 624 const ctf_funcinfo_t *ctc, const ctf_id_t *argv) 625 { 626 ctf_dtdef_t *dtd; 627 ctf_id_t type; 628 uint_t vlen; 629 ctf_id_t *vdat = NULL; 630 631 if (ctc == NULL || (ctc->ctc_flags & ~CTF_FUNC_VARARG) != 0 || 632 (ctc->ctc_argc != 0 && argv == NULL)) 633 return (ctf_set_errno(fp, EINVAL)); 634 635 vlen = ctc->ctc_argc; 636 if (ctc->ctc_flags & CTF_FUNC_VARARG) 637 vlen++; /* add trailing zero to indicate varargs (see below) */ 638 639 if (vlen > CTF_MAX_VLEN) 640 return (ctf_set_errno(fp, EOVERFLOW)); 641 642 if (vlen != 0 && (vdat = ctf_alloc(sizeof (ctf_id_t) * vlen)) == NULL) 643 return (ctf_set_errno(fp, EAGAIN)); 644 645 if ((type = ctf_add_generic(fp, flag, NULL, &dtd)) == CTF_ERR) { 646 ctf_free(vdat, sizeof (ctf_id_t) * vlen); 647 return (CTF_ERR); /* errno is set for us */ 648 } 649 650 dtd->dtd_data.ctt_info = CTF_TYPE_INFO(CTF_K_FUNCTION, flag, vlen); 651 dtd->dtd_data.ctt_type = (ushort_t)ctc->ctc_return; 652 653 bcopy(argv, vdat, sizeof (ctf_id_t) * ctc->ctc_argc); 654 if (ctc->ctc_flags & CTF_FUNC_VARARG) 655 vdat[vlen - 1] = 0; /* add trailing zero to indicate varargs */ 656 dtd->dtd_u.dtu_argv = vdat; 657 658 return (type); 659 } 660 661 ctf_id_t 662 ctf_add_struct(ctf_file_t *fp, uint_t flag, const char *name) 663 { 664 ctf_dtdef_t *dtd; 665 ctf_id_t type; 666 667 if ((type = ctf_add_generic(fp, flag, name, &dtd)) == CTF_ERR) 668 return (CTF_ERR); /* errno is set for us */ 669 670 dtd->dtd_data.ctt_info = CTF_TYPE_INFO(CTF_K_STRUCT, flag, 0); 671 return (type); 672 } 673 674 ctf_id_t 675 ctf_add_union(ctf_file_t *fp, uint_t flag, const char *name) 676 { 677 ctf_dtdef_t *dtd; 678 ctf_id_t type; 679 680 if ((type = ctf_add_generic(fp, flag, name, &dtd)) == CTF_ERR) 681 return (CTF_ERR); /* errno is set for us */ 682 683 dtd->dtd_data.ctt_info = CTF_TYPE_INFO(CTF_K_UNION, flag, 0); 684 return (type); 685 } 686 687 ctf_id_t 688 ctf_add_enum(ctf_file_t *fp, uint_t flag, const char *name) 689 { 690 ctf_dtdef_t *dtd; 691 ctf_id_t type; 692 693 if ((type = ctf_add_generic(fp, flag, name, &dtd)) == CTF_ERR) 694 return (CTF_ERR); /* errno is set for us */ 695 696 dtd->dtd_data.ctt_info = CTF_TYPE_INFO(CTF_K_ENUM, flag, 0); 697 dtd->dtd_data.ctt_size = fp->ctf_dmodel->ctd_int; 698 699 return (type); 700 } 701 702 ctf_id_t 703 ctf_add_forward(ctf_file_t *fp, uint_t flag, const char *name, uint_t kind) 704 { 705 ctf_dtdef_t *dtd; 706 ctf_id_t type; 707 708 if (kind != CTF_K_STRUCT && kind != CTF_K_UNION && kind != CTF_K_ENUM) 709 return (ctf_set_errno(fp, ECTF_NOTSUE)); 710 711 if ((type = ctf_add_generic(fp, flag, name, &dtd)) == CTF_ERR) 712 return (CTF_ERR); /* errno is set for us */ 713 714 dtd->dtd_data.ctt_info = CTF_TYPE_INFO(CTF_K_FORWARD, flag, 0); 715 return (type); 716 } 717 718 ctf_id_t 719 ctf_add_typedef(ctf_file_t *fp, uint_t flag, const char *name, ctf_id_t ref) 720 { 721 ctf_dtdef_t *dtd; 722 ctf_id_t type; 723 724 if (ref == CTF_ERR || ref < 0 || ref > CTF_MAX_TYPE) 725 return (ctf_set_errno(fp, EINVAL)); 726 727 if ((type = ctf_add_generic(fp, flag, name, &dtd)) == CTF_ERR) 728 return (CTF_ERR); /* errno is set for us */ 729 730 dtd->dtd_data.ctt_info = CTF_TYPE_INFO(CTF_K_TYPEDEF, flag, 0); 731 dtd->dtd_data.ctt_type = (ushort_t)ref; 732 733 return (type); 734 } 735 736 ctf_id_t 737 ctf_add_volatile(ctf_file_t *fp, uint_t flag, ctf_id_t ref) 738 { 739 return (ctf_add_reftype(fp, flag, ref, CTF_K_VOLATILE)); 740 } 741 742 ctf_id_t 743 ctf_add_const(ctf_file_t *fp, uint_t flag, ctf_id_t ref) 744 { 745 return (ctf_add_reftype(fp, flag, ref, CTF_K_CONST)); 746 } 747 748 ctf_id_t 749 ctf_add_restrict(ctf_file_t *fp, uint_t flag, ctf_id_t ref) 750 { 751 return (ctf_add_reftype(fp, flag, ref, CTF_K_RESTRICT)); 752 } 753 754 int 755 ctf_add_enumerator(ctf_file_t *fp, ctf_id_t enid, const char *name, int value) 756 { 757 ctf_dtdef_t *dtd; 758 ctf_dmdef_t *dmd; 759 760 uint_t kind, vlen, root; 761 char *s; 762 763 if (name == NULL) 764 return (ctf_set_errno(fp, EINVAL)); 765 766 if (!(fp->ctf_flags & LCTF_RDWR)) 767 return (ctf_set_errno(fp, ECTF_RDONLY)); 768 769 for (dtd = ctf_list_next(&fp->ctf_dtdefs); 770 dtd != NULL; dtd = ctf_list_next(dtd)) { 771 if (dtd->dtd_type == enid) 772 break; 773 } 774 775 if (dtd == NULL) 776 return (ctf_set_errno(fp, ECTF_BADID)); 777 778 kind = CTF_INFO_KIND(dtd->dtd_data.ctt_info); 779 root = CTF_INFO_ISROOT(dtd->dtd_data.ctt_info); 780 vlen = CTF_INFO_VLEN(dtd->dtd_data.ctt_info); 781 782 if (kind != CTF_K_ENUM) 783 return (ctf_set_errno(fp, ECTF_NOTENUM)); 784 785 if (vlen == CTF_MAX_VLEN) 786 return (ctf_set_errno(fp, ECTF_DTFULL)); 787 788 for (dmd = ctf_list_next(&dtd->dtd_u.dtu_members); 789 dmd != NULL; dmd = ctf_list_next(dmd)) { 790 if (strcmp(dmd->dmd_name, name) == 0) 791 return (ctf_set_errno(fp, ECTF_DUPMEMBER)); 792 } 793 794 if ((dmd = ctf_alloc(sizeof (ctf_dmdef_t))) == NULL) 795 return (ctf_set_errno(fp, EAGAIN)); 796 797 if ((s = ctf_strdup(name)) == NULL) { 798 ctf_free(dmd, sizeof (ctf_dmdef_t)); 799 return (ctf_set_errno(fp, EAGAIN)); 800 } 801 802 dmd->dmd_name = s; 803 dmd->dmd_type = CTF_ERR; 804 dmd->dmd_offset = 0; 805 dmd->dmd_value = value; 806 807 dtd->dtd_data.ctt_info = CTF_TYPE_INFO(kind, root, vlen + 1); 808 ctf_list_append(&dtd->dtd_u.dtu_members, dmd); 809 810 fp->ctf_dtstrlen += strlen(s) + 1; 811 fp->ctf_flags |= LCTF_DIRTY; 812 813 return (0); 814 } 815 816 int 817 ctf_add_member(ctf_file_t *fp, ctf_id_t souid, const char *name, ctf_id_t type) 818 { 819 ctf_dtdef_t *dtd; 820 ctf_dmdef_t *dmd; 821 822 ssize_t msize, malign, ssize; 823 uint_t kind, vlen, root; 824 char *s = NULL; 825 826 if (!(fp->ctf_flags & LCTF_RDWR)) 827 return (ctf_set_errno(fp, ECTF_RDONLY)); 828 829 for (dtd = ctf_list_next(&fp->ctf_dtdefs); 830 dtd != NULL; dtd = ctf_list_next(dtd)) { 831 if (dtd->dtd_type == souid) 832 break; 833 } 834 835 if (dtd == NULL) 836 return (ctf_set_errno(fp, ECTF_BADID)); 837 838 kind = CTF_INFO_KIND(dtd->dtd_data.ctt_info); 839 root = CTF_INFO_ISROOT(dtd->dtd_data.ctt_info); 840 vlen = CTF_INFO_VLEN(dtd->dtd_data.ctt_info); 841 842 if (kind != CTF_K_STRUCT && kind != CTF_K_UNION) 843 return (ctf_set_errno(fp, ECTF_NOTSOU)); 844 845 if (vlen == CTF_MAX_VLEN) 846 return (ctf_set_errno(fp, ECTF_DTFULL)); 847 848 if (name != NULL) { 849 for (dmd = ctf_list_next(&dtd->dtd_u.dtu_members); 850 dmd != NULL; dmd = ctf_list_next(dmd)) { 851 if (dmd->dmd_name != NULL && 852 strcmp(dmd->dmd_name, name) == 0) 853 return (ctf_set_errno(fp, ECTF_DUPMEMBER)); 854 } 855 } 856 857 if ((msize = ctf_type_size(fp, type)) == CTF_ERR || 858 (malign = ctf_type_align(fp, type)) == CTF_ERR) 859 return (CTF_ERR); /* errno is set for us */ 860 861 if ((dmd = ctf_alloc(sizeof (ctf_dmdef_t))) == NULL) 862 return (ctf_set_errno(fp, EAGAIN)); 863 864 if (name != NULL && (s = ctf_strdup(name)) == NULL) { 865 ctf_free(dmd, sizeof (ctf_dmdef_t)); 866 return (ctf_set_errno(fp, EAGAIN)); 867 } 868 869 dmd->dmd_name = s; 870 dmd->dmd_type = type; 871 dmd->dmd_value = -1; 872 873 if (kind == CTF_K_STRUCT && vlen != 0) { 874 ctf_dmdef_t *lmd = ctf_list_prev(&dtd->dtd_u.dtu_members); 875 ctf_id_t ltype = ctf_type_resolve(fp, lmd->dmd_type); 876 size_t off = lmd->dmd_offset; 877 878 ctf_encoding_t linfo; 879 ssize_t lsize; 880 881 if (ctf_type_encoding(fp, ltype, &linfo) != CTF_ERR) 882 off += linfo.cte_bits; 883 else if ((lsize = ctf_type_size(fp, ltype)) != CTF_ERR) 884 off += lsize * NBBY; 885 886 /* 887 * Round up the offset of the end of the last member to the 888 * next byte boundary, convert 'off' to bytes, and then round 889 * it up again to the next multiple of the alignment required 890 * by the new member. Finally, convert back to bits and store 891 * the result in dmd_offset. Technically we could do more 892 * efficient packing if the new member is a bit-field, but 893 * we're the "compiler" and ANSI says we can do as we choose. 894 */ 895 off = roundup(off, NBBY) / NBBY; 896 off = roundup(off, MAX(malign, 1)); 897 dmd->dmd_offset = off * NBBY; 898 ssize = off + msize; 899 } else { 900 dmd->dmd_offset = 0; 901 ssize = ctf_get_ctt_size(fp, &dtd->dtd_data, NULL, NULL); 902 ssize = MAX(ssize, msize); 903 } 904 905 if (ssize > CTF_MAX_SIZE) { 906 dtd->dtd_data.ctt_size = CTF_LSIZE_SENT; 907 dtd->dtd_data.ctt_lsizehi = CTF_SIZE_TO_LSIZE_HI(ssize); 908 dtd->dtd_data.ctt_lsizelo = CTF_SIZE_TO_LSIZE_LO(ssize); 909 } else 910 dtd->dtd_data.ctt_size = (ushort_t)ssize; 911 912 dtd->dtd_data.ctt_info = CTF_TYPE_INFO(kind, root, vlen + 1); 913 ctf_list_append(&dtd->dtd_u.dtu_members, dmd); 914 915 if (s != NULL) 916 fp->ctf_dtstrlen += strlen(s) + 1; 917 918 fp->ctf_flags |= LCTF_DIRTY; 919 return (0); 920 } 921 922 static int 923 enumcmp(const char *name, int value, void *arg) 924 { 925 ctf_bundle_t *ctb = arg; 926 int bvalue; 927 928 return (ctf_enum_value(ctb->ctb_file, ctb->ctb_type, 929 name, &bvalue) == CTF_ERR || value != bvalue); 930 } 931 932 static int 933 enumadd(const char *name, int value, void *arg) 934 { 935 ctf_bundle_t *ctb = arg; 936 937 return (ctf_add_enumerator(ctb->ctb_file, ctb->ctb_type, 938 name, value) == CTF_ERR); 939 } 940 941 /*ARGSUSED*/ 942 static int 943 membcmp(const char *name, ctf_id_t type, ulong_t offset, void *arg) 944 { 945 ctf_bundle_t *ctb = arg; 946 ctf_membinfo_t ctm; 947 948 return (ctf_member_info(ctb->ctb_file, ctb->ctb_type, 949 name, &ctm) == CTF_ERR || ctm.ctm_offset != offset); 950 } 951 952 static int 953 membadd(const char *name, ctf_id_t type, ulong_t offset, void *arg) 954 { 955 ctf_bundle_t *ctb = arg; 956 ctf_dmdef_t *dmd; 957 char *s = NULL; 958 959 if ((dmd = ctf_alloc(sizeof (ctf_dmdef_t))) == NULL) 960 return (ctf_set_errno(ctb->ctb_file, EAGAIN)); 961 962 if (name != NULL && (s = ctf_strdup(name)) == NULL) { 963 ctf_free(dmd, sizeof (ctf_dmdef_t)); 964 return (ctf_set_errno(ctb->ctb_file, EAGAIN)); 965 } 966 967 /* 968 * For now, dmd_type is copied as the src_fp's type; it is reset to an 969 * equivalent dst_fp type by a final loop in ctf_add_type(), below. 970 */ 971 dmd->dmd_name = s; 972 dmd->dmd_type = type; 973 dmd->dmd_offset = offset; 974 dmd->dmd_value = -1; 975 976 ctf_list_append(&ctb->ctb_dtd->dtd_u.dtu_members, dmd); 977 978 if (s != NULL) 979 ctb->ctb_file->ctf_dtstrlen += strlen(s) + 1; 980 981 ctb->ctb_file->ctf_flags |= LCTF_DIRTY; 982 return (0); 983 } 984 985 /* 986 * The ctf_add_type routine is used to copy a type from a source CTF container 987 * to a dynamic destination container. This routine operates recursively by 988 * following the source type's links and embedded member types. If the 989 * destination container already contains a named type which has the same 990 * attributes, then we succeed and return this type but no changes occur. 991 */ 992 ctf_id_t 993 ctf_add_type(ctf_file_t *dst_fp, ctf_file_t *src_fp, ctf_id_t src_type) 994 { 995 ctf_id_t dst_type = CTF_ERR; 996 uint_t dst_kind = CTF_K_UNKNOWN; 997 998 const ctf_type_t *tp; 999 const char *name; 1000 uint_t kind, flag, vlen; 1001 1002 ctf_bundle_t src, dst; 1003 ctf_encoding_t src_en, dst_en; 1004 ctf_arinfo_t src_ar, dst_ar; 1005 1006 ctf_dtdef_t *dtd; 1007 ctf_funcinfo_t ctc; 1008 ssize_t size; 1009 1010 ctf_hash_t *hp; 1011 ctf_helem_t *hep; 1012 1013 if (!(dst_fp->ctf_flags & LCTF_RDWR)) 1014 return (ctf_set_errno(dst_fp, ECTF_RDONLY)); 1015 1016 if ((tp = ctf_lookup_by_id(&src_fp, src_type)) == NULL) 1017 return (ctf_set_errno(dst_fp, ctf_errno(src_fp))); 1018 1019 name = ctf_strptr(src_fp, tp->ctt_name); 1020 kind = LCTF_INFO_KIND(src_fp, tp->ctt_info); 1021 flag = LCTF_INFO_ROOT(src_fp, tp->ctt_info); 1022 vlen = LCTF_INFO_VLEN(src_fp, tp->ctt_info); 1023 1024 switch (kind) { 1025 case CTF_K_STRUCT: 1026 hp = &dst_fp->ctf_structs; 1027 break; 1028 case CTF_K_UNION: 1029 hp = &dst_fp->ctf_unions; 1030 break; 1031 case CTF_K_ENUM: 1032 hp = &dst_fp->ctf_enums; 1033 break; 1034 default: 1035 hp = &dst_fp->ctf_names; 1036 break; 1037 } 1038 1039 /* 1040 * If the source type has a name and is a root type (visible at the 1041 * top-level scope), lookup the name in the destination container and 1042 * verify that it is of the same kind before we do anything else. 1043 */ 1044 if ((flag & CTF_ADD_ROOT) && name[0] != '\0' && 1045 (hep = ctf_hash_lookup(hp, dst_fp, name, strlen(name))) != NULL) { 1046 dst_type = (ctf_id_t)hep->h_type; 1047 dst_kind = ctf_type_kind(dst_fp, dst_type); 1048 } 1049 1050 /* 1051 * If an identically named dst_type exists, fail with ECTF_CONFLICT 1052 * unless dst_type is a forward declaration and src_type is a struct, 1053 * union, or enum (i.e. the definition of the previous forward decl). 1054 */ 1055 if (dst_type != CTF_ERR && dst_kind != kind && ( 1056 dst_kind != CTF_K_FORWARD || (kind != CTF_K_ENUM && 1057 kind != CTF_K_STRUCT && kind != CTF_K_UNION))) 1058 return (ctf_set_errno(dst_fp, ECTF_CONFLICT)); 1059 1060 /* 1061 * If the non-empty name was not found in the appropriate hash, search 1062 * the list of pending dynamic definitions that are not yet committed. 1063 * If a matching name and kind are found, assume this is the type that 1064 * we are looking for. This is necessary to permit ctf_add_type() to 1065 * operate recursively on entities such as a struct that contains a 1066 * pointer member that refers to the same struct type. 1067 */ 1068 if (dst_type == CTF_ERR && name[0] != '\0') { 1069 for (dtd = ctf_list_prev(&dst_fp->ctf_dtdefs); dtd != NULL && 1070 dtd->dtd_type > dst_fp->ctf_dtoldid; 1071 dtd = ctf_list_prev(dtd)) { 1072 if (CTF_INFO_KIND(dtd->dtd_data.ctt_info) == kind && 1073 dtd->dtd_name != NULL && 1074 strcmp(dtd->dtd_name, name) == 0) 1075 return (dtd->dtd_type); 1076 } 1077 } 1078 1079 src.ctb_file = src_fp; 1080 src.ctb_type = src_type; 1081 src.ctb_dtd = NULL; 1082 1083 dst.ctb_file = dst_fp; 1084 dst.ctb_type = dst_type; 1085 dst.ctb_dtd = NULL; 1086 1087 /* 1088 * Now perform kind-specific processing. If dst_type is CTF_ERR, then 1089 * we add a new type with the same properties as src_type to dst_fp. 1090 * If dst_type is not CTF_ERR, then we verify that dst_type has the 1091 * same attributes as src_type. We recurse for embedded references. 1092 */ 1093 switch (kind) { 1094 case CTF_K_INTEGER: 1095 case CTF_K_FLOAT: 1096 if (ctf_type_encoding(src_fp, src_type, &src_en) != 0) 1097 return (ctf_set_errno(dst_fp, ctf_errno(src_fp))); 1098 1099 if (dst_type != CTF_ERR) { 1100 if (ctf_type_encoding(dst_fp, dst_type, &dst_en) != 0) 1101 return (CTF_ERR); /* errno is set for us */ 1102 1103 if (bcmp(&src_en, &dst_en, sizeof (ctf_encoding_t))) 1104 return (ctf_set_errno(dst_fp, ECTF_CONFLICT)); 1105 1106 } else if (kind == CTF_K_INTEGER) { 1107 dst_type = ctf_add_integer(dst_fp, flag, name, &src_en); 1108 } else 1109 dst_type = ctf_add_float(dst_fp, flag, name, &src_en); 1110 break; 1111 1112 case CTF_K_POINTER: 1113 case CTF_K_VOLATILE: 1114 case CTF_K_CONST: 1115 case CTF_K_RESTRICT: 1116 src_type = ctf_type_reference(src_fp, src_type); 1117 src_type = ctf_add_type(dst_fp, src_fp, src_type); 1118 1119 if (src_type == CTF_ERR) 1120 return (CTF_ERR); /* errno is set for us */ 1121 1122 dst_type = ctf_add_reftype(dst_fp, flag, src_type, kind); 1123 break; 1124 1125 case CTF_K_ARRAY: 1126 if (ctf_array_info(src_fp, src_type, &src_ar) == CTF_ERR) 1127 return (ctf_set_errno(dst_fp, ctf_errno(src_fp))); 1128 1129 src_ar.ctr_contents = 1130 ctf_add_type(dst_fp, src_fp, src_ar.ctr_contents); 1131 src_ar.ctr_index = 1132 ctf_add_type(dst_fp, src_fp, src_ar.ctr_index); 1133 src_ar.ctr_nelems = src_ar.ctr_nelems; 1134 1135 if (src_ar.ctr_contents == CTF_ERR || 1136 src_ar.ctr_index == CTF_ERR) 1137 return (CTF_ERR); /* errno is set for us */ 1138 1139 if (dst_type != CTF_ERR) { 1140 if (ctf_array_info(dst_fp, dst_type, &dst_ar) != 0) 1141 return (CTF_ERR); /* errno is set for us */ 1142 1143 if (bcmp(&src_ar, &dst_ar, sizeof (ctf_arinfo_t))) 1144 return (ctf_set_errno(dst_fp, ECTF_CONFLICT)); 1145 } else 1146 dst_type = ctf_add_array(dst_fp, flag, &src_ar); 1147 break; 1148 1149 case CTF_K_FUNCTION: 1150 ctc.ctc_return = ctf_add_type(dst_fp, src_fp, tp->ctt_type); 1151 ctc.ctc_argc = 0; 1152 ctc.ctc_flags = 0; 1153 1154 if (ctc.ctc_return == CTF_ERR) 1155 return (CTF_ERR); /* errno is set for us */ 1156 1157 dst_type = ctf_add_function(dst_fp, flag, &ctc, NULL); 1158 break; 1159 1160 case CTF_K_STRUCT: 1161 case CTF_K_UNION: { 1162 ctf_dmdef_t *dmd; 1163 int errs = 0; 1164 1165 /* 1166 * Technically to match a struct or union we need to check both 1167 * ways (src members vs. dst, dst members vs. src) but we make 1168 * this more optimal by only checking src vs. dst and comparing 1169 * the total size of the structure (which we must do anyway) 1170 * which covers the possibility of dst members not in src. 1171 * This optimization can be defeated for unions, but is so 1172 * pathological as to render it irrelevant for our purposes. 1173 */ 1174 if (dst_type != CTF_ERR && dst_kind != CTF_K_FORWARD) { 1175 if (ctf_type_size(src_fp, src_type) != 1176 ctf_type_size(dst_fp, dst_type)) 1177 return (ctf_set_errno(dst_fp, ECTF_CONFLICT)); 1178 1179 if (ctf_member_iter(src_fp, src_type, membcmp, &dst)) 1180 return (ctf_set_errno(dst_fp, ECTF_CONFLICT)); 1181 1182 break; 1183 } 1184 1185 /* 1186 * Unlike the other cases, copying structs and unions is done 1187 * manually so as to avoid repeated lookups in ctf_add_member 1188 * and to ensure the exact same member offsets as in src_type. 1189 */ 1190 dst_type = ctf_add_generic(dst_fp, flag, name, &dtd); 1191 if (dst_type == CTF_ERR) 1192 return (CTF_ERR); /* errno is set for us */ 1193 1194 dst.ctb_type = dst_type; 1195 dst.ctb_dtd = dtd; 1196 1197 if (ctf_member_iter(src_fp, src_type, membadd, &dst) != 0) 1198 errs++; /* increment errs and fail at bottom of case */ 1199 1200 if ((size = ctf_type_size(src_fp, src_type)) > CTF_MAX_SIZE) { 1201 dtd->dtd_data.ctt_size = CTF_LSIZE_SENT; 1202 dtd->dtd_data.ctt_lsizehi = CTF_SIZE_TO_LSIZE_HI(size); 1203 dtd->dtd_data.ctt_lsizelo = CTF_SIZE_TO_LSIZE_LO(size); 1204 } else 1205 dtd->dtd_data.ctt_size = (ushort_t)size; 1206 1207 dtd->dtd_data.ctt_info = CTF_TYPE_INFO(kind, flag, vlen); 1208 1209 /* 1210 * Make a final pass through the members changing each dmd_type 1211 * (a src_fp type) to an equivalent type in dst_fp. We pass 1212 * through all members, leaving any that fail set to CTF_ERR. 1213 */ 1214 for (dmd = ctf_list_next(&dtd->dtd_u.dtu_members); 1215 dmd != NULL; dmd = ctf_list_next(dmd)) { 1216 if ((dmd->dmd_type = ctf_add_type(dst_fp, src_fp, 1217 dmd->dmd_type)) == CTF_ERR) 1218 errs++; 1219 } 1220 1221 if (errs) 1222 return (CTF_ERR); /* errno is set for us */ 1223 break; 1224 } 1225 1226 case CTF_K_ENUM: 1227 if (dst_type != CTF_ERR && dst_kind != CTF_K_FORWARD) { 1228 if (ctf_enum_iter(src_fp, src_type, enumcmp, &dst) || 1229 ctf_enum_iter(dst_fp, dst_type, enumcmp, &src)) 1230 return (ctf_set_errno(dst_fp, ECTF_CONFLICT)); 1231 } else { 1232 dst_type = ctf_add_enum(dst_fp, flag, name); 1233 if ((dst.ctb_type = dst_type) == CTF_ERR || 1234 ctf_enum_iter(src_fp, src_type, enumadd, &dst)) 1235 return (CTF_ERR); /* errno is set for us */ 1236 } 1237 break; 1238 1239 case CTF_K_FORWARD: 1240 if (dst_type == CTF_ERR) { 1241 dst_type = ctf_add_forward(dst_fp, 1242 flag, name, CTF_K_STRUCT); /* assume STRUCT */ 1243 } 1244 break; 1245 1246 case CTF_K_TYPEDEF: 1247 src_type = ctf_type_reference(src_fp, src_type); 1248 src_type = ctf_add_type(dst_fp, src_fp, src_type); 1249 1250 if (src_type == CTF_ERR) 1251 return (CTF_ERR); /* errno is set for us */ 1252 1253 /* 1254 * If dst_type is not CTF_ERR at this point, we should check if 1255 * ctf_type_reference(dst_fp, dst_type) != src_type and if so 1256 * fail with ECTF_CONFLICT. However, this causes problems with 1257 * <sys/types.h> typedefs that vary based on things like if 1258 * _ILP32x then pid_t is int otherwise long. We therefore omit 1259 * this check and assume that if the identically named typedef 1260 * already exists in dst_fp, it is correct or equivalent. 1261 */ 1262 if (dst_type == CTF_ERR) { 1263 dst_type = ctf_add_typedef(dst_fp, flag, 1264 name, src_type); 1265 } 1266 break; 1267 1268 default: 1269 return (ctf_set_errno(dst_fp, ECTF_CORRUPT)); 1270 } 1271 1272 return (dst_type); 1273 } 1274