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