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