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