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